You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C Socket编程:客户端输入与服务端交互代码问题排查

C语言Socket客户端与服务端代码修正方案

核心问题梳理

客户端问题

  • scanf参数不匹配:原代码scanf("%c",&letter);中,letter是字符数组,&letter的类型是char(*)[1024],与scanf期望的char*类型不符,导致编译警告。应改为scanf(" %c", letter);(数组名本身指向首地址,前面加空格跳过输入缓冲区的空白字符)。
  • 逻辑顺序错误:原代码先执行read循环等待服务端数据,再发送指令,这会导致程序卡在read步骤(服务端需先收到指令才会返回数据),必须调整为先发送指令,再接收响应。
  • 发送/输出错误:发送时不应传递整个数组长度sizeof(letter),只需发送单个字符(长度为1);输出服务端响应时,printf("%c", recvBuff);错误,应使用%s输出字符串。

服务端问题

  • 字符比较错误:原代码from_client == 't'将数组指针与字符直接比较,逻辑完全错误,应取数组首元素from_client[0] == 't'进行判断。
  • 字符串赋值错误:sendBuff == "Marcus Baker"是比较操作而非赋值,需用strcpy(sendBuff, "Marcus Baker");复制字符串。
  • 发送长度错误:发送时不应传递整个数组长度sizeof(sendBuff),应发送实际字符串长度strlen(sendBuff),避免发送多余空字符。
  • 退出逻辑不完善:收到'q'时直接return 0会导致服务端异常退出,需先发送响应、关闭当前连接,再退出循环。
  • 未处理recv返回值:未判断recv的返回值,当客户端断开时会导致无效操作,需处理recv_len <= 0的情况。

修正后的服务端代码

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

int main(int argc, char *argv[])
{
    int listenfd, connfd;
    struct sockaddr_in serv_addr; 

    char sendBuff[1025];
    char from_client[1025];
    time_t ticks; 
    ssize_t recv_len;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    memset(&serv_addr, 0, sizeof(serv_addr));
    memset(sendBuff, 0, sizeof(sendBuff)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(5000); 

    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 
    listen(listenfd, 10); 

    while(1)
    {
        connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 
        if (connfd < 0) {
            perror("accept error");
            continue;
        }

        recv_len = recv(connfd, from_client, sizeof(from_client)-1, 0);
        if (recv_len <= 0) {
            close(connfd);
            continue;
        }
        from_client[recv_len] = '\0'; // 添加字符串结束符
        printf("Received: %c\n", from_client[0]);

        if(from_client[0] == 't')
        {
            ticks = time(NULL);
            snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks));
            write(connfd, sendBuff, strlen(sendBuff));
        }
        else if(from_client[0] == 'n')
        {
            strcpy(sendBuff, "Marcus Baker");
            send(connfd, sendBuff, strlen(sendBuff), 0);
        }
        else if(from_client[0] == 'i')
        {
            strcpy(sendBuff, "201604543");
            send(connfd, sendBuff, strlen(sendBuff), 0);
        }
        else if(from_client[0] == 'q')
        {
            strcpy(sendBuff, "Quit");
            send(connfd, sendBuff, strlen(sendBuff), 0);
            close(connfd);
            break; // 退出循环,关闭服务端
        }
        else
        {
            strcpy(sendBuff, "Invalid command");
            send(connfd, sendBuff, strlen(sendBuff), 0);
        }

        close(connfd);
        sleep(1);
     }
    close(listenfd);
    return 0;
}

修正后的客户端代码

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

int main(int argc, char *argv[])
{
    int sockfd, n = 0;
    char letter[2]; // 仅存储单个字符+字符串结束符
    char recvBuff[1024];
    struct sockaddr_in serv_addr; 

    if(argc != 2)
    {
        printf("\n Usage: %s <ip of server> \n", argv[0]);
        return 1;
    } 

    printf("Enter a Character (t, n, i, q): ");
    // 空格跳过空白字符,避免读取输入缓冲区残留的换行符
    scanf(" %c", letter);

    memset(recvBuff, 0, sizeof(recvBuff));
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Error : Could not create socket \n");
        return 1;
    } 

    memset(&serv_addr, 0, sizeof(serv_addr)); 

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(5000); 

    if(inet_pton(AF_INET, argv[1], &serv_addr.sin_addr) <= 0)
    {
        printf("\n inet_pton error occured\n");
        return 1;
    } 

    if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
       printf("\n Error : Connect Failed \n");
       return 1;
    } 

    // 先发送指令给服务端
    int toServer = send(sockfd, letter, 1, 0);
    if (toServer < 0) {
        perror("send error");
        close(sockfd);
        return 1;
    }
    printf("Letter Sent\n");

    // 接收服务端响应
    n = read(sockfd, recvBuff, sizeof(recvBuff)-1);
    if (n > 0) {
        recvBuff[n] = '\0';
        printf("Server Response: %s\n", recvBuff);
    } else if (n < 0) {
        printf("\n Read error \n");
    }

    close(sockfd);
    return 0;
}

内容的提问来源于stack exchange,提问作者Marcus Baker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 04:01:19