Linux TCP Socket实现进程间通信

Linux Socket由内核实现,全双工方式,单个客户端进程通过多条连接连上服务端后,并发发送请求并接收响应,最后关闭连接。
TCP是协议无实体,Socket是具体实现。

服务端
初始化Socket->绑定地址和端口->监听端口->accept阻塞等待客户端连接->处理请求并响应
客户端
初始化Socket->连接服务端->发送请求->读取数据->关闭连接

common.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
 
#define PORT 3000
#define MAX_CHARS 1000
#define MAX_CONNECTIONS 5

struct message {
    char name[10];
    int type;
};

client.c

#include "common.h"

int main(int argc, char **argv)
{
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd == -1)
    {
        printf("create socket error: %s\n", strerror(errno));
        exit(1);
    }
 
    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
 
    if (connect(socket_fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
    {
        printf("connect error: %s\n", strerror(errno));
        exit(1);
    }
 
    // 从终端读取字符串并发送
    // char msg[MAX_CHARS];
    // printf("send:\n");
    // fgets(msg, MAX_CHARS, stdin);
    // if (send(socket_fd, msg, strlen(msg), 0) == -1)
    // {
    //     printf("send error: %s\n", strerror(errno));
    //     exit(1);
    // }

    char buff[MAX_CHARS];
    struct message msg;
    strcpy(msg.name, "test");
    msg.type = 100;
    memcpy(buff, &msg, sizeof(msg));
    if (send(socket_fd, buff, sizeof(buff), 0) == -1)
    {
        printf("send error: %s\n", strerror(errno));
        exit(1);
    }
 
    char buf[MAX_CHARS];
    int n;
    n = recv(socket_fd, buf, MAX_CHARS, 0);
    if (n == -1)
    {
        perror("receive error");
        exit(1);
    }
 
    buf[n] = '\0';
    printf("receive: %s", buf);
 
    close(socket_fd);
    exit(0);
}

server.c

#include "common.h"
 
int main(int argc, char **argv)
{
    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd == -1)
    {
        printf("create socket error: %s\n", strerror(errno));
        exit(1);
    }
 
    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    // INADDR_ANY表示本机地址
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(PORT);
 
    if (bind(socket_fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
    {
        printf("bind socket error: %s\n", strerror(errno));
        exit(1);
    }
 
    if (listen(socket_fd, MAX_CONNECTIONS) == -1)
    {
        printf("listen socket error: %s\n", strerror(errno));
        exit(1);
    }
 
    printf("handle client request\n");
    while (1)
    {
        int connect_fd = accept(socket_fd, (struct sockaddr *)NULL, NULL);
        if (connect_fd == -1)
        {
            printf("accept socket error: %s", strerror(errno));
            continue;
        }

        char buff[MAX_CHARS];
        int n = recv(connect_fd, buff, sizeof(buff), 0);
        struct message *msg = (struct message *)buff;
        printf("%s %d\n", msg->name, msg->type);

        // int n;
        // char buff[1000];
        // n = recv(connect_fd, buff, MAX_CHARS, 0);
        // 末尾设置字符数组结束标志
        // buff[n] = '\0';
        // printf("receive: %s", buff);
 
        // 创建子进程来处理请求
        if (!fork())
        {
            char resp[100] = "handle complete\n";
            if (send(connect_fd, resp, strlen(resp), 0) == -1)
                perror("send error");
            close(connect_fd);
            exit(0);
        }
 
        close(connect_fd);
    }
 
    close(socket_fd);
    exit(0);
}

posted on 2023-07-30 13:56  王景迁  阅读(111)  评论(0编辑  收藏  举报

导航