首页 > 代码库 > 《UNIX网络编程》之点对点通信

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

思路:

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

代码如下:

客户端:

/*************************************************************************    > 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网络编程》之点对点通信