码迷,mamicode.com
首页 > 其他好文 > 详细

《UNIX网络编程》之多客户连接服务端,可重用套接字对

时间:2014-10-06 00:32:59      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   os   使用   ar   for   strong   

该网络编程之客户端与服务端程序模板支持:

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

标签:style   blog   color   io   os   使用   ar   for   strong   

原文地址:http://www.cnblogs.com/wiessharling/p/4007474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!