• 《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.
    ");
                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
    ", 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;
    }
  • 相关阅读:
    线段树专辑—— pku 1436 Horizontally Visible Segments
    线段树专辑——pku 3667 Hotel
    线段树专辑——hdu 1540 Tunnel Warfare
    线段树专辑—— hdu 1828 Picture
    线段树专辑—— hdu 1542 Atlantis
    线段树专辑 —— pku 2482 Stars in Your Window
    线段树专辑 —— pku 3225 Help with Intervals
    线段树专辑—— hdu 1255 覆盖的面积
    线段树专辑—— hdu 3016 Man Down
    Ajax跨域访问
  • 原文地址:https://www.cnblogs.com/wiessharling/p/4007474.html
Copyright © 2020-2023  润新知