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

C语言TCP客户端连接后立即断开及功能调用问题咨询

解决你的C Socket客户端问题

Hey there! Let's fix your two issues step by step—first the immediate disconnect problem, then building the input-handling logic to match the server's manageConnection behavior.

问题1:客户端连接后立即断开

The root cause here is simple: your client's main function calls connect() and then immediately return 0, which exits the program entirely. When the program exits, the socket descriptor is closed automatically, dropping the connection to the server.

问题2:实现类似manageConnection的交互功能

We need to add a loop that:

  • Reads input from your terminal
  • Sends the input to the server
  • Receives and prints the server's response
  • Handles the exit condition (when you enter X)

Also, there's a critical bug in your original client code that's overriding the server address you pass via command line—we'll fix that too.


修改后的完整客户端代码

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

#define PORTNUMBER 7777
#define BUF_LEN 512

// 类似服务器manageConnection的客户端处理函数
void handleClientInteraction(int sockfd) {
    char inputBuf[BUF_LEN];
    char serverResponse[BUF_LEN];
    ssize_t bytesRead, bytesSent;

    // 先读取服务器的初始欢迎信息
    bytesRead = read(sockfd, serverResponse, BUF_LEN - 1);
    if (bytesRead > 0) {
        serverResponse[bytesRead] = '\0';
        printf("%s", serverResponse);
    }

    while (1) {
        // 提示用户输入
        printf("> ");
        fflush(stdout);

        // 读取用户输入(直到换行符)
        if (fgets(inputBuf, BUF_LEN, stdin) == NULL) {
            perror("Error reading input");
            break;
        }

        // 检查退出条件:输入的第一个字符是'X'(不管后面有没有内容)
        if (inputBuf[0] == 'X') {
            // 发送X给服务器,然后退出循环
            send(sockfd, inputBuf, strlen(inputBuf), 0);
            printf("Disconnecting from server...\n");
            break;
        }

        // 发送输入到服务器(注意fgets会保留换行符,服务器正好用换行符判断输入结束)
        bytesSent = send(sockfd, inputBuf, strlen(inputBuf), 0);
        if (bytesSent < 0) {
            perror("Error sending data to server");
            break;
        }

        // 读取服务器的响应
        memset(serverResponse, 0, BUF_LEN);
        bytesRead = read(sockfd, serverResponse, BUF_LEN - 1);
        if (bytesRead <= 0) {
            if (bytesRead == 0) {
                printf("Server closed the connection.\n");
            } else {
                perror("Error reading server response");
            }
            break;
        }

        // 打印服务器响应
        printf("%s", serverResponse);
    }

    close(sockfd);
}

int main(int argc, char * argv[]) {
    int csd;
    struct sockaddr_in server;
    struct hostent* server_host;

    // 检查命令行参数是否正确
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <server-hostname-or-ip>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    server_host = gethostbyname(argv[1]);
    if (server_host == NULL) {
        herror("Error in gethostbyname()");
        exit(EXIT_FAILURE);
    }

    // 创建客户端socket
    if ( (csd = socket(PF_INET, SOCK_STREAM, 0)) < 0 ) {
        perror("Error in socket()");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址结构体
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    // 复制服务器地址(修复原代码的错误:不要覆盖这个地址)
    memcpy(&server.sin_addr.s_addr, server_host->h_addr_list[0], server_host->h_length);
    server.sin_port = htons(PORTNUMBER);

    // 连接服务器
    if ( connect(csd, (struct sockaddr * ) & server, sizeof(server)) < 0) {
        perror("Error in connect()");
        close(csd);
        exit(EXIT_FAILURE);
    }

    printf("Connected to server successfully!\n");

    // 启动交互逻辑,替代原代码的直接退出
    handleClientInteraction(csd);

    return 0;
}

关键修改和解释

  1. 修复服务器地址覆盖问题
    原代码中server.sin_addr.s_addr = htonl(INADDR_ANY);是错误的——INADDR_ANY用于服务器绑定所有本地接口,客户端应该使用传入的服务器地址。这行代码会覆盖你通过argv[1]指定的服务器地址,我们已经删除了它。

  2. 添加handleClientInteraction函数
    这个函数模拟了服务器manageConnection的逻辑:

    • 首先读取并打印服务器的欢迎信息
    • 进入循环,等待用户输入
    • 使用fgets读取用户输入(保留换行符,因为服务器用换行符判断输入完成)
    • 检测退出条件(输入以X开头)
    • 发送输入到服务器,然后接收并打印响应
    • 处理连接断开或错误情况
  3. 避免立即退出
    连接成功后,我们调用handleClientInteraction而不是直接return 0,这样程序会保持运行直到用户输入X或连接中断。


如何使用

编译客户端代码:

gcc client.c -o client

运行客户端(替换localhost为你的服务器IP/主机名):

./client localhost

现在你可以输入字符串提交给服务器处理,输入X即可断开连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:32:33