socket 实现的简单的p2p服务程序

来源:互联网 发布:哈利波特英文原版淘宝 编辑:程序博客网 时间:2024/06/05 03:43


p2pclient.c


#include <unistd.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/types.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <signal.h>#include <arpa/inet.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>/* int socket(int domain, int type, int protocol); *//* int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); //man 2 bind struct sockaddr { sa_family_t sa_family; char        sa_data[14]; } //man 7 ip struct sockaddr_in { sa_family_t    sin_family; // address family: AF_INET u_int16_t      sin_port;   // port in network byte order struct in_addr sin_addr;   // internet address }; //Internet address. struct in_addr { u_int32_t      s_addr;     //address in network byte order }; *///int listen(int sockfd, int backlog);//accept 接受一个新的连接 ,这个新的连接是一个主动套接字/*   int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); On success, accept() returns a non-negative integer that is a descriptor for the accepted socket.   On  error, -1 is returned, and errno is set appropriately. int conn = 0; */int main(){    int sockfd = 0;    sockfd = socket(PF_INET, SOCK_STREAM, 0);    if (sockfd == -1)    {        perror("fun socket\n");        exit(0);    }    //设置客服端链接的tcpip结构体信息    struct sockaddr_in srvaddr;    //协议族    srvaddr.sin_family = AF_INET;    //设置端口    srvaddr.sin_port = htons(8001);    //设置ip    srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //127.0.0.1    //srvaddr.sin_addr.s_addr = inet_addr(INADDR_ANY); //绑定本机的任意一个地址    //客服端链接    if (connect(sockfd, (struct sockaddr*) (&srvaddr), sizeof(srvaddr)) < 0)    {        perror("fun socket\n");        exit(0);    }    pid_t pid = fork();    if(pid == -1)    {        perror("fork");        return -1;    }    else if(pid == 0)    {        //child process,read process        char revbuf[1024] = { 0 };        while(1)        {            int ret = read(sockfd, revbuf, sizeof(revbuf));            if (ret == 0)            {                //如果在读的过程中,对方已经关闭,tcpip协议会返回一个0数据包                printf("对方已关闭\n");                break;            }            else if (ret < 0)            {                perror("读数据失败\n");                break;            }            fputs(revbuf, stdout); //服务器端收到数据,打印屏幕            memset(revbuf,0x00,sizeof(revbuf));        }    }    else    {        char sendbuf[1024] = { 0 };        while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)        {            write(sockfd, sendbuf, strlen(sendbuf)); //服务器端回发信息            memset(sendbuf, 0, sizeof(sendbuf));        }    }    close(sockfd);    return 0;}

p2pserver.c


#include <unistd.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/types.h>#include <fcntl.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <signal.h>#include <arpa/inet.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>/* int socket(int domain, int type, int protocol); *//* int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen); //man 2 bind struct sockaddr { sa_family_t sa_family; char        sa_data[14]; } //man 7 ip struct sockaddr_in { sa_family_t    sin_family; // address family: AF_INET u_int16_t      sin_port;   // port in network byte order struct in_addr sin_addr;   // internet address }; //Internet address. struct in_addr { u_int32_t      s_addr;     //address in network byte order }; *///int listen(int sockfd, int backlog);/*   int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); On success, accept() returns a non-negative integer that is a descriptor for the accepted socket.   On  error, -1 is returned, and errno is set appropriately. int conn = 0; */int main(){    int sockfd = 0;    //创建socket    sockfd = socket(PF_INET, SOCK_STREAM, 0);    if (sockfd == -1)    {        perror("fun socket\n");        exit(0);    }    //定义socket结构体    struct sockaddr_in srvaddr;    //设置协议族    srvaddr.sin_family = AF_INET;    //设置端口    srvaddr.sin_port = htons(8001);    //增加ip地址    srvaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //127.0.0.1    //srvaddr.sin_addr.s_addr = inet_addr(INADDR_ANY); //绑定本机的任意一个地址    //绑定IP    if (bind(sockfd, (struct sockaddr *) &srvaddr, sizeof(srvaddr)) < 0)    {        perror("fun bind\n");        exit(0);    }    //一但调用listen函数,这个套接字sockfd将变成被动套接字;只能接受连接,不能主动的发送连接    //listen 做了两个队列。。。。。。    // 队列由内核管理,一部分是完成三次握手的,一部分是没有完成三次握手的。    if (listen(sockfd, SOMAXCONN) < 0)    {        perror("fun listen\n");        exit(0);    }    //struct sockaddr peeraddr;  //通用ip    //socklen_t perrlen ;    struct sockaddr_in peeraddr; //tcpip地址结构    socklen_t peerlen = sizeof(peeraddr);    unsigned int conn = 0;    //accept接受已经完成三次握手的链接,没有链接会阻塞直到有链接    conn = accept(sockfd, (struct sockaddr *) &peeraddr,            (socklen_t *) &peerlen);    if (conn == -1)    {        perror("fun listen\n");        exit(0);    }    pid_t pid = fork();    if(pid == -1)    {        perror("fork");        return -1;    }    else if(pid == 0)    {        //this is child process        //child read        char revbuf[1024] = { 0 };        while(1)        {            int ret = read(conn, revbuf, sizeof(revbuf));            if (ret == 0)            {                //如果在读的过程中,对方已经关闭,tcpip协议会返回一个0数据包                printf("对方已关闭\n");                break;            }            else if (ret < 0)            {                perror("读数据失败\n");                break;            }            fputs(revbuf, stdout); //服务器端收到数据,打印屏幕            memset(revbuf,0x00,sizeof(revbuf));        }    }    else    {        //this is parent process        //parent process write        char sendbuf[1024] = { 0 };        while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)        {            //向服务写数据            //ssize_t write(int fd, const void *buf, size_t count);            // 从buf中读取count大小的数据存入文件描述符为fd的文件中。            write(conn, sendbuf, strlen(sendbuf)); //服务器端回发信息            memset(sendbuf, 0, sizeof(sendbuf));        }    }    close(conn);    close(sockfd);    return 0;}


0 0