1、功能說明:LINUX平臺TCP編程實現client端像server端傳輸文件,支持多client。linux
2、TCP/IP協議實現面向鏈接的通訊的實現原理編程
3、代碼實現socket
一、server.cide
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 }
二、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 }
4、編譯運行命令說明spa
一、編譯.net
client:gcc -o client client.c命令行
server:gcc -o server server.ccode
二、運行server
client端:./client <server IP> <端口號> <上傳文件名>
server端:./server <端口號> <保存爲文件名>
其中,server端先運行,client端與server端的端口號必須一致而且不能與已知端口衝突(如可設爲1234)。
若只在某一PC的linux系統上進行客戶端服務端文件通訊測試,需注意:
server IP可設爲回送地址127.0.0.1;
可開多個終端來模擬客戶端和服務端。
5、測試過程及結果
一、編譯源文件
client:gcc -o client client.c
server:gcc -o server server.c
二、新建客戶端待上傳文件分別爲file1.txt、file2.txt、file3.txt,其內容爲
這是第一(二/三)個測試文件!
三、運行服務端程序,服務端進入等待接收數據狀態。命令執行後文件路徑下生成文件loadfile.txt
./server 1234 loadfile.txt
四、打開一個新的終端,做爲第一個客戶端。運行客戶端程序,發送數據。命令執行後file1.txt文件內容被寫入loadfile.txt
./client 127.0.0.1 1234 file1.txt
五、在第一個客戶端對應的終端再執行如下命令。命令執行後file2.txt文件內容被寫入loadfile.txt
./client 127.0.0.1 1234 file2.txt
六、再打開一個新的終端,做爲第二個客戶端,執行如下命令。命令執行後file3.txt文件內容被寫入loadfile.txt
./client 127.0.0.1 1234 file3.txt
七、操做截圖
服務端命令行
第一個客戶端命令行
第二個客戶端命令行
第一個客戶端文件
第二個客戶端文件
服務端文件
6、參考連接
http://blog.csdn.net/yueguanghaidao/article/details/7035248
http://blog.csdn.net/haluoluo211/article/details/44115273