0Pricing
C Academy · 课时

TCP 客户端

连接并发送数据

TCP 客户端 是 CoddyKit 上的免费 C Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C Academy 课程共包含 4 节课。

构建 TCP 客户端

TCP 客户端连接到服务器,然后发送和接收数据。它的生命周期比服务器短:创建套接字、连接、通信,然后关闭。

步骤 1:创建套接字

与服务器一样,创建用于 IPv4 TCP 的流式套接字。

#include <sys/socket.h>
#include <stdio.h>

int make_client_socket(void) {
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd < 0) perror("socket");
    return fd;
}

步骤 2:描述服务器

将服务器的端口和 IP 填入 sockaddr_in。使用 inet_pton 将点分十进制 IP 字符串转换为二进制形式。

#include <arpa/inet.h>
#include <netinet/in.h>

int set_server(struct sockaddr_in *addr, const char *ip, unsigned short port) {
    addr->sin_family = AF_INET;
    addr->sin_port = htons(port);
    return inet_pton(AF_INET, ip, &addr->sin_addr); /* 1 on success */
}

步骤 3:连接

connect() 会与服务器执行 TCP 握手。成功后套接字即可传输数据;失败时会设置 errno(例如连接被拒绝)。

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>

int do_connect(int fd, struct sockaddr_in *addr) {
    if (connect(fd, (struct sockaddr *)addr, sizeof *addr) < 0) {
        perror("connect"); return -1;
    }
    return 0;
}

无需绑定

客户端通常跳过 bind:内核会在 connect 期间自动分配一个临时源端口。只有在需要指定源端口时,才需要为客户端绑定端口。

步骤 4:发送数据

连接后,使用 send 写入请求。请循环发送,以确保整个缓冲区都已发出。

#include <sys/socket.h>
#include <string.h>

int send_all(int fd, const char *data) {
    size_t left = strlen(data);
    const char *p = data;
    while (left > 0) {
        ssize_t n = send(fd, p, left, 0);
        if (n <= 0) return -1;
        p += n; left -= (size_t)n;
    }
    return 0;
}

步骤 5:接收回复

使用 recv 读取服务器的响应。将缓冲区当作字符串处理之前,请先在末尾添加空字符。

#include <sys/socket.h>
#include <stdio.h>

void read_reply(int fd) {
    char buf[512];
    ssize_t n = recv(fd, buf, sizeof buf - 1, 0);
    if (n > 0) { buf[n] = 0; printf("server said: %s\n", buf); }
    else if (n == 0) printf("server closed connection\n");
}

读取直到连接关闭

一次 recv 可能无法返回完整响应。请循环读取,直到 recv 返回 0(表示对端已关闭连接),以便读取分段到达的完整回复。

#include <sys/socket.h>
#include <stdio.h>

void drain(int fd) {
    char buf[256]; ssize_t n;
    while ((n = recv(fd, buf, sizeof buf, 0)) > 0)
        fwrite(buf, 1, (size_t)n, stdout);
}

步骤 6:关闭

调用 close(fd) 结束连接并释放描述符。这会发送 TCP FIN,使服务器知道客户端已经完成操作。

#include <unistd.h>

void finish(int fd) {
    close(fd);
}

使用 shutdown 半关闭

shutdown(fd, SHUT_WR) 只关闭写入方向,同时仍允许客户端读取回复,并以此表示请求结束。这对先请求、后响应的协议很有用。

处理连接失败

常见的客户端错误包括:ECONNREFUSED(没有服务器在监听)、ETIMEDOUT(主机无法访问)以及 EHOSTUNREACH。请始终检查 connect,并向用户清晰地报告失败原因。

快速检查

测试您对 TCP 客户端的理解。

回顾

您构建了一个 TCP 客户端。

  • 创建 socket,然后连接到服务器的 sockaddr_in
  • 无需 bind;内核会选择源端口
  • 发送请求,接收回复(循环接收完整数据)
  • 完成后 close 或 shutdown;处理连接失败

常见问题解答

「TCP 客户端」课时是免费的吗?

是的 — 「TCP 客户端」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C Academy 课程的其余内容,请升级到 CoddyKit PRO。 C Academy 课程共包含 4 节课。

「TCP 客户端」这节课中我会学到什么?

连接并发送数据 你通过在浏览器中直接运行的动手代码来练习 C Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「TCP 客户端」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C Academy 课中编写并运行代码吗?

能。每节 C Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 套接字概述
  2. TCP 服务器
  3. TCP 客户端
  4. 处理多个客户端
← 返回 C Academy