標籤:return inux sea workspace alt close lis socket pre
環境:Linux
語言:C++
通訊方式:TCP
下面用TCP協議編寫一個簡單的伺服器、用戶端,其中伺服器端一直監聽原生6666號連接埠。如果收到串連請求,將接收請求並接收用戶端發來的訊息;用戶端與伺服器端建立串連。串連建立成功後,讀取檔案內容(/root/workspace/socket-picture/bizhi.jpg),發送給伺服器端,伺服器端建立new1.jpg檔案,將已接收的檔案內容儲存到new1.jpg中,new1.jpg在目前的目錄下;
Server.cpp
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<errno.h> 5 #include<sys/types.h> 6 #include<sys/socket.h> 7 #include<netinet/in.h> 8 #include<unistd.h> 9 10 #define MAXLINE 409611 12 int main(int argc, char** argv){13 int listenfd, connfd;14 struct sockaddr_in servaddr;15 char buff[4096];16 FILE *fp;17 int n;18 19 if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){20 printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);21 return 0;22 }23 printf("----init socket----\n");24 25 memset(&servaddr, 0, sizeof(servaddr));26 servaddr.sin_family = AF_INET;27 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);28 servaddr.sin_port = htons(6666);29 //設定連接埠可重用30 int contain;31 setsockopt(listenfd,SOL_SOCKET, SO_REUSEADDR, &contain, sizeof(int));32 33 if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){34 printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);35 return 0;36 }37 printf("----bind sucess----\n");38 39 if( listen(listenfd, 10) == -1){40 printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);41 return 0;42 }43 if((fp = fopen("new1.jpg","ab") ) == NULL )44 {45 printf("File.\n");46 close(listenfd);47 exit(1);48 }49 50 printf("======waiting for client‘s request======\n");51 while(1){52 struct sockaddr_in client_addr;53 socklen_t size=sizeof(client_addr);54 if( (connfd = accept(listenfd, (struct sockaddr*)&client_addr, &size)) == -1){55 printf("accept socket error: %s(errno: %d)",strerror(errno),errno);56 continue;57 }58 while(1){59 n = read(connfd, buff, MAXLINE);60 if(n == 0)61 break;62 fwrite(buff, 1, n, fp);63 }64 buff[n] = ‘\0‘;65 printf("recv msg from client: %s\n", buff);66 close(connfd);67 fclose(fp);68 }69 close(listenfd);70 return 0;71 }
Client.cpp
1 #include <stdio.h> 2 #include <errno.h> 3 #include <string.h> 4 #include <netdb.h> 5 #include <sys/types.h> 6 #include <netinet/in.h> 7 #include <sys/socket.h> 8 #include <stdlib.h> 9 #include <unistd.h>10 #include <arpa/inet.h>11 #include <netdb.h>12 #define MAXLINE 409613 14 int main(int argc, char** argv){15 int sockfd, len;16 char buffer[MAXLINE];17 struct sockaddr_in servaddr;18 FILE *fq;19 20 if( argc != 2){21 printf("usage: ./client <ipaddress>\n");22 return 0;23 }24 25 if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){26 printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);27 return 0;28 }29 30 memset(&servaddr, 0, sizeof(servaddr));31 servaddr.sin_family = AF_INET;32 servaddr.sin_port = htons(6666);33 if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){34 printf("inet_pton error for %s\n",argv[1]);35 return 0;36 }37 38 if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){39 printf("connect error: %s(errno: %d)\n",strerror(errno),errno);40 return 0;41 }42 if( ( fq = fopen("/root/workspace/socket-picture/bizhi.jpg","rb") ) == NULL ){43 printf("File open.\n");44 close(sockfd);45 exit(1);46 }47 48 bzero(buffer,sizeof(buffer));49 while(!feof(fq)){50 len = fread(buffer, 1, sizeof(buffer), fq);51 if(len != write(sockfd, buffer, len)){52 printf("write.\n");53 break;54 }55 }56 close(sockfd);57 fclose(fq);58 59 return 0;60 }
makefile
1 all:server client 2 server:server.o 3 g++ -g -o server server.o 4 client:client.o 5 g++ -g -o client client.o 6 server.o:server.cpp 7 g++ -g -c server.cpp 8 client.o:client.cpp 9 g++ -g -c client.cpp10 clean:all11 rm all
執行make命令後,產生server和client兩個可執行檔。分別開啟兩個終端視窗,一個執行./server命令,一個執行./client 127.0.0.1命令,表示連上原生6666連接埠,執行./server命令的要先執行。執行./client 127.0.0.1命令後,client用戶端執行完畢直接退出,這時可以看到server的那個終端視窗輸出“recv msg from client:”。開啟目前的目錄(指的是可執行檔server所在的目錄),可看到new1.jpg檔案已經產生,雙擊開啟,檔案內容沒有丟失。
Linux C++ TCP Socket傳輸檔案或圖片執行個體