首页 > 代码库 > 《UNIX网络编程》之多客户连接服务端,可重用套接字对
《UNIX网络编程》之多客户连接服务端,可重用套接字对
该网络编程之客户端与服务端程序模板支持:
1. 多客户端同时连接服务端,即服务程序可以同时为多个客户端服务;
2. 服务端支持套接字对重用,即即使处于TIME_WAIT状态,仍可支持服务端重启;
3. 服务端可以发现客户端是否已断开连接;
4. 支持客户端标准输入会显,服务端从标准输出显示客户端所输入内容。
程序如下,记下该模板以备再次使用:
客户端程序如下:
/************************************************************************* > File Name: p2pcli.c > Author: ma6174 > Mail: ma6174@163.com > Created Time: Sun 05 Oct 2014 09:26:40 PM HKT ************************************************************************/#include<stdio.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <netinet/in.h>#include <string.h>#include <sys/socket.h>#include <arpa/inet.h>#define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0)int main(int argc, char **argv){ int sockfd; struct sockaddr_in servaddr; if(argc != 2) { //printf("usage: p2pcli <IPaddress> "); //exit(0); ERR_EXIT("usage: p2pcli <IPaddress> "); } sockfd = socket(AF_INET, SOCK_STREAM, 0); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(5188); servaddr.sin_addr.s_addr = inet_addr(argv[1]); if(connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) { ERR_EXIT("connect"); } //communication char sendbuf[1024] = {0}; char recvbuf[1024] = {0}; while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL) { //send to server. write(sockfd, sendbuf, strlen(sendbuf)); //read from server to display. read(sockfd, recvbuf, sizeof(recvbuf)); //display fputs(recvbuf, stdout); memset(sendbuf, 0, sizeof(sendbuf)); memset(recvbuf, 0, sizeof(recvbuf)); } close(sockfd); return 0;}
服务端程序如下:
/************************************************************************* > File Name: p2psrv.c > Author: ma6174 > Mail: ma6174@163.com > Created Time: Sun 05 Oct 2014 08:27:06 PM HKT ************************************************************************/#include<stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#include <string.h>#include <arpa/inet.h>#define ERR_EXIT(m) do { perror(m); exit(EXIT_FAILURE); }while(0)void do_service(int connfd){ //communication char recvbuf[1024]; while(1) { memset(recvbuf, 0, sizeof(recvbuf)); int ret = read(connfd, recvbuf, sizeof(recvbuf)); if(ret == 0) { printf("client close.\n"); break; } else if(ret == -1) { break; } else { fputs(recvbuf, stdout); write(connfd, recvbuf, ret); } }}int main(){ int listenfd; if( (listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { ERR_EXIT("socket"); } struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(5188); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //reuse address int on = 1; if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { ERR_EXIT("setsockopt"); } if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) { ERR_EXIT("bind"); } if(listen(listenfd, SOMAXCONN) < 0) { ERR_EXIT("listen"); } struct sockaddr_in peeraddr; socklen_t peerlen = sizeof(peeraddr); int connfd; //muti client pid_t pid; while(1) { if( (connfd = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0 ) { ERR_EXIT("accept"); } printf("ip=%s, port=%d\n", inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port)); pid = fork(); if(pid == -1) { ERR_EXIT("fork"); } else if(pid == 0) { //child close(listenfd); do_service(connfd); exit(0); } else { close(connfd); } } close(connfd); close(listenfd); return 0;}
《UNIX网络编程》之多客户连接服务端,可重用套接字对
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。