下面用TCP协议编写一个简单的服务器、客户端,其中服务器端一直监听本机的6666号端口。如果收到连接请求,将接收请求并接收客户端发来的消息;客户端与服务器端建立连接。连接建立成功后,读取文件内容(/root/workspace/socket-picture/bizhi.jpg),发送给服务器端,服务器端新建new1.jpg文件,将接收到的文件内容保存到new1.jpg中,new1.jpg在当前目录下;
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<unistd.h> #define MAXLINE 4096 int main(int argc, char** argv){ int listenfd, connfd; struct sockaddr_in servaddr; char buff[4096]; FILE *fp; int n; if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ printf("create socket error: %s(errno: %d)\n",strerror(errno),errno); return 0; } printf("----init socket----\n"); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(6666); //设置端口可重用 int contain; setsockopt(listenfd,SOL_SOCKET, SO_REUSEADDR, &contain, sizeof(int)); if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); return 0; } printf("----bind sucess----\n"); if( listen(listenfd, 10) == -1){ printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); return 0; } if((fp = fopen("new1.jpg","ab") ) == NULL ) { printf("File.\n"); close(listenfd); exit(1); } printf("======waiting for client's request======\n"); while(1){ struct sockaddr_in client_addr; socklen_t size=sizeof(client_addr); if( (connfd = accept(listenfd, (struct sockaddr*)&client_addr, &size)) == -1){ printf("accept socket error: %s(errno: %d)",strerror(errno),errno); continue; } while(1){ n = read(connfd, buff, MAXLINE); if(n == 0) break; fwrite(buff, 1, n, fp); } buff[n] = '\0'; printf("recv msg from client: %s\n", buff); close(connfd); fclose(fp); } close(listenfd); return 0; }
Client.cpp
#include <stdio.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <stdlib.h> #include <unistd.h> #include <arpa/inet.h> #include <netdb.h> #define MAXLINE 4096 int main(int argc, char** argv){ int sockfd, len; char buffer[MAXLINE]; struct sockaddr_in servaddr; FILE *fq; if( argc != 2){ printf("usage: ./client <ipaddress>\n"); return 0; } if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("create socket error: %s(errno: %d)\n", strerror(errno),errno); return 0; } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(6666); if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){ printf("inet_pton error for %s\n",argv[1]); return 0; } if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ printf("connect error: %s(errno: %d)\n",strerror(errno),errno); return 0; } if( ( fq = fopen("/root/workspace/socket-picture/bizhi.jpg","rb") ) == NULL ){ printf("File open.\n"); close(sockfd); exit(1); } bzero(buffer,sizeof(buffer)); while(!feof(fq)){ len = fread(buffer, 1, sizeof(buffer), fq); if(len != write(sockfd, buffer, len)){ printf("write.\n"); break; } } close(sockfd); fclose(fq); return 0; }
makefile
all:server client server:server.o g++ -g -o server server.o client:client.o g++ -g -o client client.o server.o:server.cpp g++ -g -c server.cpp client.o:client.cpp g++ -g -c client.cpp clean:all 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文件已经生成,双击打开,文件内容没有丢失。