以下是一个用Linux C编写的本地回环测试程序,包括客户端非阻塞的重连服务器:

服务器端代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#define PORT 9999
#define MAXLINE 1024

int main()
{
    int sockfd, connfd;
    struct sockaddr_in servaddr, cliaddr;
    socklen_t len = sizeof(cliaddr);
    char buff[MAXLINE];

    // 创建socket
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    // 初始化地址结构体
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(PORT);

    // 绑定地址
    if (bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {
        perror("bind error");
        exit(EXIT_FAILURE);
    }

    // 监听
    if (listen(sockfd, 5) == -1) {
        perror("listen error");
        exit(EXIT_FAILURE);
    }

    printf("Server listening on port %d...\n", PORT);

    while (1) {
        // 接收客户端连接
        if ((connfd = accept(sockfd, (struct sockaddr*)&cliaddr, &len)) == -1) {
            perror("accept error");
            exit(EXIT_FAILURE);
        }

        printf("Connection established. Client address: %s, port: %d\n",
            inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

        // 读取客户端数据并回送
        while (1) {
            memset(buff, 0, sizeof(buff));
            ssize_t n = recv(connfd, buff, sizeof(buff), 0);
            if (n == -1) {
                perror("recv error");
                exit(EXIT_FAILURE);
            } else if (n == 0) {
                printf("Connection closed.\n");
                close(connfd);
                break;
            } else {
                printf("Received message: %s", buff);
                send(connfd, buff, n, 0);
            }
        }
    }

    return 0;
}

客户端代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>

#define PORT 9999
#define MAXLINE 1024

int main()
{
    int sockfd;
    struct sockaddr_in servaddr;
    char buff[MAXLINE];
    int flags;

    // 创建socket
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    // 初始化地址结构体
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    servaddr.sin_port = htons(PORT);

    // 设置非阻塞模式
    if ((flags = fcntl(sockfd, F_GETFL, 0)) == -1) {
        perror("fcntl error");
        exit(EXIT_FAILURE);
    }
    flags |= O_NONBLOCK;
    if (fcntl(sockfd, F_SETFL, flags) == -1) {
        perror("fcntl error");
        exit(EXIT_FAILURE);
    }

    // 连接服务器
    while (1) {
        if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {
            if (errno == EINPROGRESS) {
                printf("Connecting to server...\n");
                sleep(1);
                continue;
            } else {
                perror("connect error");
                exit(EXIT_FAILURE);
            }
        } else {
            printf("Connection established.\n");
            break;
        }
    }

    while (1) {
        // 从标准输入读取数据
        memset(buff, 0, sizeof(buff));
        if (fgets(buff, MAXLINE, stdin) == NULL) {
            break;
        }

        // 发送数据到服务器
        ssize_t n = send(sockfd, buff, strlen(buff), 0);
        if (n == -1) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                printf("Send buffer full.\n");
            } else {
                perror("send error");
                exit(EXIT_FAILURE);
            }
        } else {
            printf("Sent message: %s", buff);

            // 从服务器接收回送数据
            memset(buff, 0, sizeof(buff));
            n = recv(sockfd, buff, sizeof(buff), 0);
            if (n == -1) {
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    printf("Receive buffer empty.\n");
                } else {
                    perror("recv error");
                    exit(EXIT_FAILURE);
                }
            } else if (n == 0) {
                printf("Connection closed by server.\n");
                break;
            } else {
                printf("Received message: %s", buff);
            }
        }
    }

    close(sockfd);

    return 0;
}
``
用linux C写一个socket本地回环的测试程序包括客户端非阻塞的重连服务器

原文地址: https://www.cveoy.top/t/topic/dxiC 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录