一、功能说明:LINUX平台TCP编程实现client端像server端传输文件,支持多client。
二、TCP/IP协议实现面向连接的通信的实现原理
三、代码实现
1、server.c

1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <unistd.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h> 10 11 #define MAXLINE 1024 12 13 int main(int argc,char **argv) 14 { 15 struct sockaddr_in serv_addr; 16 struct sockaddr_in clie_addr; 17 char buf[MAXLINE]; 18 int sock_id; 19 int link_id; 20 int recv_len; 21 int write_leng; 22 int clie_addr_len; 23 FILE *fp; 24 25 if (argc != 3) 26 { 27 printf("usage :%s portnum filename\n", argv[0]); 28 exit(0); 29 } 30 /*<-----------------------------------------socket---------------------------------------------->*/ 31 if ((sock_id = socket(AF_INET, SOCK_STREAM, 0)) < 0) 32 { 33 perror("Create socket failed\n"); 34 exit(0); 35 } 36 /*<-----------------------------------------bind------------------------------------------------->*/ 37 memset(&serv_addr, 0, sizeof(serv_addr)); 38 serv_addr.sin_family = AF_INET; 39 serv_addr.sin_port = htons(atoi(argv[1])); 40 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 41 42 if (bind(sock_id, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0 ) 43 { 44 perror("Bind socket failed\n"); 45 exit(0); 46 } 47 /*<-----------------------------------------listen----------------------------------------------->*/ 48 if (-1 == listen(sock_id, 10)) 49 { 50 perror("Listen socket failed\n"); 51 exit(0); 52 } 53 /*<-------------------------------------server receive part---------------------------------->*/ 54 while (1) { 55 //”a+“ 以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留) 56 if ((fp = fopen(argv[2], "a+")) == NULL) 57 { 58 perror("Open file failed\n"); 59 exit(0); 60 } 61 clie_addr_len = sizeof(clie_addr); 62 /*<-----------------------------------------accept----------------------------------------------->*/ 63 link_id = accept(sock_id, (struct sockaddr *)&clie_addr, &clie_addr_len); 64 if (-1 == link_id) { 65 perror("Accept socket failed\n"); 66 exit(0); 67 } 68 bzero(buf, MAXLINE); 69 while (recv_len = recv(link_id, buf, MAXLINE, 0)) 70 { 71 if(recv_len < 0) 72 { 73 printf("Recieve Data From Server Failed!\n"); 74 break; 75 } 76 printf("#"); 77 write_leng = fwrite(buf, sizeof(char), recv_len, fp); 78 if (write_leng < recv_len) 79 { 80 printf("Write file failed\n"); 81 break; 82 } 83 bzero(buf,MAXLINE); 84 } 85 printf("\nFinish Recieve\n"); 86 fclose(fp); 87 close(link_id); 88 } 89 close(sock_id); 90 return 0; 91 }
2、client.c

1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <unistd.h> 6 #include <fcntl.h> 7 #include <sys/types.h> 8 #include <sys/socket.h> 9 #include <netinet/in.h> 10 #include <arpa/inet.h> 11 12 #define MAXLINE 1024 13 14 int main(int argc,char **argv) 15 { 16 struct sockaddr_in serv_addr; 17 char buf[MAXLINE]; 18 int sock_id; 19 int read_len; 20 int send_len; 21 FILE *fp; 22 int i_ret; 23 24 if (argc != 4) 25 { 26 printf("usage :%s ipaddr portnum filename\n", argv[0]); 27 exit(0); 28 } 29 30 if ((fp = fopen(argv[3],"r")) == NULL) 31 { 32 perror("Open file failed\n"); 33 exit(0); 34 } 35 36 /*<-----------------------------------------socket---------------------------------------------->*/ 37 if ((sock_id = socket(AF_INET,SOCK_STREAM,0)) < 0) { 38 perror("Create socket failed\n"); 39 exit(0); 40 } 41 /*<-----------------------------------------connect---------------------------------------------->*/ 42 memset(&serv_addr, 0, sizeof(serv_addr)); 43 serv_addr.sin_family = AF_INET; 44 serv_addr.sin_port = htons(atoi(argv[2])); 45 inet_pton(AF_INET, argv[1], &serv_addr.sin_addr); 46 47 i_ret = connect(sock_id, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)); 48 if (-1 == i_ret) 49 { 50 printf("Connect socket failed\n"); 51 return -1; 52 } 53 /*<-------------------------------------client send part---------------------------------->*/ 54 bzero(buf, MAXLINE); 55 while ((read_len = fread(buf, sizeof(char), MAXLINE, fp)) >0 ) 56 { 57 send_len = send(sock_id, buf, read_len, 0); 58 if ( send_len < 0 ) 59 { 60 perror("Send file failed\n"); 61 exit(0); 62 } 63 bzero(buf, MAXLINE); 64 } 65 66 fclose(fp); 67 close(sock_id); 68 printf("Send Finish\n"); 69 return 0; 70 }
四、编译运行命令说明
1、编译
client:gcc -o client client.c
server:gcc -o server server.c
2、运行
client端:./client <server IP> <端口号> <上传文件名>
server端:./server <端口号> <保存为文件名>
其中,server端先运行,client端与server端的端口号必须一致并且不能与已知端口冲突(如可设为1234)。
若只在某一PC的linux系统上进行客户端服务端文件通信测试,需注意:
server IP可设为回送地址127.0.0.1;
可开多个终端来模拟客户端和服务端。
五、测试过程及结果
1、编译源文件
client:gcc -o client client.c
server:gcc -o server server.c
2、新建客户端待上传文件分别为file1.txt、file2.txt、file3.txt,其内容为
这是第一(二/三)个测试文件!
3、运行服务端程序,服务端进入等待接收数据状态。命令执行后文件路径下生成文件loadfile.txt
./server 1234 loadfile.txt
4、打开一个新的终端,作为第一个客户端。运行客户端程序,发送数据。命令执行后file1.txt文件内容被写入loadfile.txt
./client 127.0.0.1 1234 file1.txt
5、在第一个客户端对应的终端再执行以下命令。命令执行后file2.txt文件内容被写入loadfile.txt
./client 127.0.0.1 1234 file2.txt
6、再打开一个新的终端,作为第二个客户端,执行以下命令。命令执行后file3.txt文件内容被写入loadfile.txt
./client 127.0.0.1 1234 file3.txt
7、操作截图
服务端命令行
第一个客户端命令行
第二个客户端命令行
第一个客户端文件
第二个客户端文件
服务端文件
六、参考链接
http://blog.csdn.net/yueguanghaidao/article/details/7035248
http://blog.csdn.net/haluoluo211/article/details/44115273