我们来试验一下socket发送和接受数据
 一共有三个文件:mysocket.h、socketServer.c、socketClient.c
 过程:
 1.将这三个文件准备好,放到一个目录下
 2.执行 gcc socketServer.c -o server.out
 3.执行 gcc socketClient.c -o client.out
 4.在一个终端窗口执行:./server.out,可以看到当前进程处于等待状态
 5.再打开另一个终端窗口执行:./client.out 1
 6.观察两个窗口的输出
 下面是三个文件的源代码,在IDE里面报红不用管,按上面的过程去执行就好。
mysocket.h:
#include <string.h> #include <errno.h> #include <sys/types.h> #include 
<sys/socket.h> #include <stdarg.h> #include <stdlib.h> #define MAXLINE 4096 
ssize_t/* Read "n" bytes from a descriptor. */ readn(int fd, void *vptr, size_t 
n) { size_t nleft; ssize_t nread; char *ptr; ptr = vptr; nleft = n; while (nleft
> 0) { if ( (nread = read(fd, ptr, nleft)) < 0) { if (errno == EINTR) nread = 0;
/* and call read() again */ else return(-1); } else if (nread == 0) break; /* 
EOF */ nleft -= nread; ptr += nread; } return n - nleft; /* return >= 0 */ } 
ssize_t/* Write "n" bytes to a descriptor. */ writen(int fd, const void *vptr, 
size_t n) { size_t nleft; ssize_t nwritten; const char *ptr; ptr = vptr; nleft =
 n; while (nleft > 0) { if ( (nwritten = write(fd, ptr, nleft)) <= 0) { if (
nwritten< 0 && errno == EINTR) nwritten = 0; /* and call write() again */ else 
return(-1); /* error */ } nleft -= nwritten; ptr += nwritten; } return n; } 
static void err_doit(int, int, const char *, va_list); /* * Nonfatal error 
related to a system call. * Print a message and return. */ void err_ret(const 
char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(1, errno, fmt, ap); 
va_end(ap); } /* * Fatal error related to a system call. * Print a message and 
terminate. */ void err_sys(const char *fmt, ...) { va_list ap; va_start(ap, fmt)
; err_doit(1, errno, fmt, ap); va_end(ap); exit(1); } /* * Fatal error 
unrelated to a system call. * Error code passed as explict parameter. * Print a 
message and terminate. */ void err_exit(int error, const char *fmt, ...) { 
va_list ap; va_start(ap, fmt); err_doit(1, error, fmt, ap); va_end(ap); exit(1);
} /* * Fatal error related to a system call. * Print a message, dump core, and 
terminate. */ void err_dump(const char *fmt, ...) { va_list ap; va_start(ap, fmt
); err_doit(1, errno, fmt, ap); va_end(ap); abort(); /* dump core and terminate 
*/ exit(1); /* shouldn't get here */ } /* * Nonfatal error unrelated to a 
system call. * Print a message and return. */ void err_msg(const char *fmt, ...)
{ va_list ap; va_start(ap, fmt); err_doit(0, 0, fmt, ap); va_end(ap); } /* * 
Fatal error unrelated to a system call. * Print a message and terminate. */ void
err_quit(const char *fmt, ...) { va_list ap; va_start(ap, fmt); err_doit(0, 0, 
fmt, ap); va_end(ap); exit(1); } /* * Print a message and return to caller. * 
Caller specifies "errnoflag". */ static void err_doit(int errnoflag, int error, 
const char *fmt, va_list ap) { char buf[MAXLINE]; vsnprintf(buf, MAXLINE, fmt, 
ap); if (errnoflag) snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s", 
strerror(error)); strcat(buf, "\n"); fflush(stdout); /* in case stdout and 
stderr are the same */ fputs(buf, stderr); fflush(NULL); /* flushes all stdio 
output streams */ } 
socketServer.h:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<netinet/in.h> 
#include<sys/socket.h> #include<sys/wait.h> #include "mysocket.h" void read_data
(int sockfd){ ssize_t n; char buf[1024]; int time = 0; while(1){ fprintf(stdout,
"block in read\n"); if((n = readn(sockfd, buf,1024)) == 0){ return; } time++; 
fprintf(stdout, "1K read for %d \n", time); usleep(10000); } } int main(int argc
, char **argv){ int listenfd, connfd; socklen_t clilen; struct sockaddr_in 
cliaddr, servaddr; // 创建 socket 套接字,bind 到对应地址和端口,并开始调用 listen 接口监听 listenfd = 
socket(AF_INET, SOCK_STREAM, 0); if(listenfd == -1){ perror("socket"); exit(1); 
} bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.
sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(12345); /* bind 
到本地地址,端口号为12345 */ if(bind(listenfd, (const struct sockaddr *) &servaddr, sizeof
(servaddr))){ perror("bind"); exit(1); } /* listen的backlog 为 1024 */ if(listen(
listenfd, 1024)){ perror("listen"); exit(1); } // 循环等待连接,通过 accept 
获取实际的连接,并开始读取数据 while(1){ clilen = sizeof(cliaddr); connfd = accept(listenfd, (
struct sockaddr *) &cliaddr, &clilen); if(connfd == -1){ perror("accept"); exit(
1); } // 实际每次读取 1K 数据,之后休眠 1 秒,用来模拟服务器端处理时延 read_data(connfd); close(connfd); } 
} 
socketClient.c:
#include<stdio.h> #include<string.h> #include<netinet/in.h> #include
<sys/socket.h> #include<sys/wait.h> #include <arpa/inet.h> #include "mysocket.h"
//# define MESSAGE_SIZE 10240000 # define MESSAGE_SIZE 1024000 // 
改小这个参数,同时Server的睡眠时间加长,可以看到send into 
buffer很快打印出来了,而Server端还在打印,因为此时,发送的数据已经到发送端的发送缓冲区了,发送端send函数结束了 void send_data(
FILE*fp, int sockfd) { char * query; query = malloc(MESSAGE_SIZE+1); for(int i=0
; i< MESSAGE_SIZE; i++){ query[i] = 'a'; } query[MESSAGE_SIZE] = '\0'; const 
char *cp; cp = query; int remaining = strlen(query); //while循环这个例子中没用,一次就发完了 
while (remaining) { int n_written = send(sockfd, cp, remaining, 0); fprintf(
stdout, "send into buffer %ld \n", n_written); if (n_written <= 0) { perror(
"send"); return; } remaining -= n_written; printf("remaining: %d", remaining); 
cp+= n_written; } return; } int main(int argc, char **argv){ int sockfd; struct 
sockaddr_in servaddr; if(argc != 2){ err_quit("usage: tcpclient <IPaddress>"); }
 sockfd= socket(AF_INET, SOCK_STREAM, 0); if(sockfd == -1){ perror("socket"); } 
bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.
sin_port= htons(12345); inet_pton(AF_INET, argv[1], &servaddr.sin_addr); if(
connect(sockfd, (const struct sockaddr *) &servaddr, sizeof(servaddr)) == -1){ 
perror("connect"); } send_data(stdin, sockfd); exit(0); }