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

《UNIX网络编程》之点对点通信

时间:2014-10-05 23:47:39      阅读:249      评论:0      收藏:0      [点我收藏+]

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

思路:

点对点通信,其原理也比较简单,在前面回显服务器的基础上,我们分别在服务端和客户端都使用两个线程,一个线程负责发送数据包,一个线程负责接收数据包。

代码如下:

客户端:

/*************************************************************************
    > 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");
    }

    pid_t pid;
    pid = fork();
    if(pid == -1)
    {
        ERR_EXIT("fork");
    }
    else if(pid == 0)
    {
        //child
        char recvbuf[1024] = {0};
        while(1)
        {
            memset(recvbuf, 0, sizeof(recvbuf));
            int ret = read(sockfd, recvbuf, sizeof(recvbuf));
            if(ret == -1)
            {
                ERR_EXIT("read");
                break;
            }
            else if(ret == 0)
            {
                printf("peer client close.\n");
                break;
            }
            else
            {
                fputs(recvbuf, stdout);
            }
        }
        
        exit(EXIT_SUCCESS);

    }
    else
    {
        char sendbuf[1024] = {0};
        while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
        {
            //send to server.
            write(sockfd, sendbuf, strlen(sendbuf));
            memset(sendbuf, 0, sizeof(sendbuf));
        }
        exit(EXIT_SUCCESS);
    }
    //communication
    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)




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;

    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_t pid;
    pid = fork();
    if(pid == -1)
    {
        ERR_EXIT("fork");
    }
    else if(pid == 0)
    {
        //child
        char sendbuf[1024];
        memset(sendbuf, 0, sizeof(sendbuf));
        while(fgets(sendbuf, sizeof(sendbuf), stdin)  != NULL)
        {
            write(connfd, sendbuf, strlen(sendbuf));
            memset(sendbuf, 0, sizeof(sendbuf));
        }
        exit(EXIT_SUCCESS);
    }
    else
    {
        char recvbuf[1024];
        while(1)
        {
            memset(recvbuf, 0, sizeof(recvbuf));
            int ret = read(connfd, recvbuf, sizeof(recvbuf));
            if(ret == -1)
            {
                ERR_EXIT("read");
            }
            else if(ret == 0)
            {
                printf("peer client close.\n");
                break;
            }
            else
            {
                fputs(recvbuf, stdout);
            }
        }
        exit(EXIT_SUCCESS);
    }

    close(connfd);
    close(listenfd);
    return 0;
}

 

《UNIX网络编程》之点对点通信

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

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

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