点对点简单聊天程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38253837/article/details/80443647

自己用C语言写了个简单的聊天程序,客户端和服务端能够彼此接受并显示对方发来的消息。使用fork()函数,每个端有两个进程,一个进程用于向对方发送消息,另一个进程接收对方发来的消息。并运用了信号的相关知识识别对方程序是否结束。具体代码如下:

//p2pserver.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>

#define ERR_EXIT(m) \
    do \
    {   \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0);

void handler(int sig) {
    printf("recv a sig = %d\n", sig);
    exit(EXIT_SUCCESS);
}

int main(int argc, char *argv[]) {
    int listenfd;

 //   listenfd = socket(PF_INET, SOCK_STREAM, 0);
 //   listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    //creat a listen socket
    if ((listenfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
        ERR_EXIT("socket");
    }
    struct sockaddr_in servaddr;
    //init the address
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;  //#define AF_INET       PF_INET //in socket.h 
    servaddr.sin_port = htons(5188);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    // servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    // inet_aton("127.0.0.1", &servaddr.sin_addr);

    int on = 1;
    if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
        ERR_EXIT("setsockopt");
    }

    //bind the socket
    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        ERR_EXIT("bind");
    }

    //set the socket to listen status
    if (listen(listenfd, SOMAXCONN) < 0) {
        ERR_EXIT("listen");
    }
    struct sockaddr_in peeraddr;
    socklen_t peerlen = sizeof(peeraddr);
    int conn;
    if ((conn = accept(listenfd, (struct sockaddr * )&peeraddr, &peerlen)) < 0) {
        ERR_EXIT("accept");
    }

    pid_t pid;
    pid = fork();
    if (pid == -1) {
        ERR_EXIT("fork");
    }
    if (pid == 0) { //child process, send data 
        signal(SIGUSR1, handler);
        char sendbuf[1024];
        while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL) {
            write(conn, sendbuf, strlen(sendbuf));
            memset(sendbuf, 0, sizeof(sendbuf));
        }
        printf("child :%d\n", pid);
        exit(EXIT_SUCCESS);
    }        
    else {  //father process, receive data
        char recvbuf[1024];
        while (1) {
            memset(recvbuf, 0, sizeof(recvbuf));
            int ret = read(conn, recvbuf, sizeof(recvbuf));
            if (ret == -1) {
                ERR_EXIT("read");
            }
            if (ret == 0) {
                printf("peer close\n");
                break;
            }
            fputs(recvbuf, stdout);
        }
        kill(pid, SIGUSR1);
        printf("father :%d\n", pid);        
        exit(EXIT_SUCCESS);
    }

    close(listenfd);
    close(conn);

    return 0;
}
//p2pclient.c
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>

#define ERR_EXIT(m) \
    do \
    {   \
        perror(m); \
        exit(EXIT_FAILURE); \
    } while(0);

void handler(int sig) {
    printf("recv a sig = %d\n", sig);
    exit(EXIT_SUCCESS);
}


int main(int argc, char *argv[]) {
    int sockfd;

 //   listenfd = socket(PF_INET, SOCK_STREAM, 0);
 //   listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    //create a listen socket
    if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
        ERR_EXIT("socket");
    }
    struct sockaddr_in servaddr;
    //init the address 
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(5188);
    // servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    // inet_aton("127.0.0.1", &servaddr.sin_addr);

    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        ERR_EXIT("connect");
    }

    pid_t pid;
    pid = fork();
    if (pid == -1) {
        ERR_EXIT("fork");
    }
    if (pid == 0) {
        char recvbuf[1024];
        while (1) {
            memset(recvbuf, 0, sizeof(recvbuf));
            int ret = read(sockfd, recvbuf, sizeof(recvbuf));
            if (ret == -1) {
                ERR_EXIT("read");
            }
            if (ret == 0) {
                printf("peer close\n");
                break;
            }
            fputs(recvbuf, stdout);
        }
        close(sockfd);
        kill(getppid(), SIGUSR1);
    }
    else {
        signal(SIGUSR1, handler);
        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;
}

猜你喜欢

转载自blog.csdn.net/qq_38253837/article/details/80443647
今日推荐