首页 > 代码库 > 《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网络编程》之多客户连接服务端,可重用套接字对