• 《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;
    }
  • 相关阅读:
    《数据库技术基础与应用(第2版)》学习笔记——第7章~
    《数据库技术基础与应用(第2版)》学习笔记——第7章~
    《数据库技术基础与应用(第2版)》学习笔记——第6章
    《数据库技术基础与应用(第2版)》学习笔记——第6章
    《数据库技术基础与应用(第2版)》学习笔记——第5章
    《数据库技术基础与应用(第2版)》学习笔记——第5章
    方法签名_spring aop_around
    spring整合apache-shiro的简单使用
    SpringMVC_放行静态资源
    java_注解
  • 原文地址:https://www.cnblogs.com/wiessharling/p/4007474.html
Copyright © 2020-2023  润新知