手写服务器与手写客户端相连接-qwen

USER

手写服务器与手写客户端相连接

ASSISTANT

好的,我们可以使用 C 语言和 POSIX Sockets API 来实现一个基础的 TCP 服务器和客户端。这个示例将展示它们如何建立连接、发送和接收消息。

核心思路:

  1. 服务器 (Server):
    • 创建一个监听套接字 (socket)。
    • 将该套接字绑定 (bind) 到一个特定的 IP 地址和端口。
    • 开始监听 (listen) 该端口上的连接请求。
    • 接受 (accept) 一个客户端的连接,这会创建一个新的套接字用于与该客户端通信。
    • 通过这个新套接字与客户端交换数据 (recv,send)。
    • 关闭套接字 (close)。
  2. 客户端 (Client):
    • 创建一个套接字 (socket)。
    • 连接到服务器的 IP 地址和端口 (connect)。
    • 通过套接字与服务器交换数据 (send,recv)。
    • 关闭套接字 (close)。

注意事项:

  • 本示例使用localhost(127.0.0.1) 作为通信地址,适合在本机上测试。
  • 代码中包含了基本的错误检查。
  • 服务器在处理完一个客户端后会退出。若要处理多个客户端,服务器需要在accept后创建新线程或进程。
  • 编译时需要链接网络库(在 Linux/macOS 上通常不需要特殊标志,但在 Windows 上需要链接ws2_32库)。

服务器代码 (server.c)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h> // For close(), read(), write()

#include <sys/socket.h> // For socket functions

#include <netinet/in.h> // For sockaddr_in

#include <arpa/inet.h> // For inet_addr

#define PORT 8080

#define BUFFER_SIZE 1024

int main() {

int server_fd, new_socket;

struct sockaddr_in address;

int opt = 1;

int addrlen = sizeof(address);

char buffer[BUFFER_SIZE] = {0};

const char *hello = "Hello from server";

// 1. 创建服务器套接字

if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {

perror("socket failed");

exit(EXIT_FAILURE);

}

// 2. 设置套接字选项 (可选,例如允许地址重用)

if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,

&opt, sizeof(opt))) {

perror("setsockopt");

exit(EXIT_FAILURE);

}

// 3. 定义服务器地址结构

address.sin_family = AF_INET;

address.sin_addr.s_addr = inet_addr("127.0.0.1"); // 监听本地地址

address.sin_port = htons(PORT); // 监听端口

// 4. 将套接字绑定到地址

if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {

perror("bind failed");

exit(EXIT_FAILURE);

}

// 5. 开始监听

if (listen(server_fd, 3) < 0) {

perror("listen");

exit(EXIT_FAILURE);

}

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

// 6. 接受客户端连接

if ((new_socket = accept(server_fd, (struct sockaddr *)&address,

(socklen_t*)&addrlen)) < 0) {

perror("accept");

exit(EXIT_FAILURE);

}

printf("Client connected.\n");

// 7. 与客户端通信

int valread = read(new_socket, buffer, BUFFER_SIZE);

if (valread > 0) {

printf("Client said: %s\n", buffer);

}

send(new_socket, hello, strlen(hello), 0);

printf("Hello message sent to client\n");

// 8. 清理

close(new_socket);

close(server_fd);

return 0;

}

客户端代码 (client.c)

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h> // For close(), read(), write()

#include <sys/socket.h> // For socket functions

#include <netinet/in.h> // For sockaddr_in

#include <arpa/inet.h> // For inet_addr

#define PORT 8080

#define IP "127.0.0.1" // 服务器IP地址

#define BUFFER_SIZE 1024

int main() {

int sock = 0;

struct sockaddr_in serv_addr;

char *hello = "Hello from client";

char buffer[BUFFER_SIZE] = {0};

// 1. 创建客户端套接字

if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {

printf("\n Socket creation error \n");

return -1;

}

serv_addr.sin_family = AF_INET;

serv_addr.sin_port = htons(PORT);

// 2. 将 IP 地址从字符串转换为网络字节序

if(inet_pton(AF_INET, IP, &serv_addr.sin_addr)<=0) {

printf("\nInvalid address/ Address not supported \n");

return -1;

}

// 3. 连接到服务器

if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {

printf("\nConnection Failed \n");

return -1;

}

printf("Connected to server.\n");

// 4. 与服务器通信

send(sock, hello, strlen(hello), 0);

printf("Hello message sent to server\n");

int valread = read(sock, buffer, BUFFER_SIZE);

if (valread > 0) {

printf("Server said: %s\n", buffer);

}

// 5. 清理

close(sock);

return 0;

}

编译和运行

  1. 编译:

gcc -o server server.c

gcc -o client client.c

  1. 运行:
    • 首先,在一个终端窗口中启动服务器:./server

你会看到 "Server listening on port 8080..." 的提示。

    • 然后,在另一个终端窗口中运行客户端:./client
    • 回到服务器窗口,你应该能看到 "Client connected." 和 "Client said: Hello from client"。
    • 回到客户端窗口,你应该能看到 "Connected to server." 和 "Server said: Hello from server"。

这样,手写的 C 语言服务器和客户端就成功连接并交换了消息。

相关推荐
西岸行者3 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意3 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码3 天前
嵌入式学习路线
学习
毛小茛3 天前
计算机系统概论——校验码
学习
babe小鑫3 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms4 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下4 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。4 天前
2026.2.25监控学习
学习
im_AMBER4 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J4 天前
从“Hello World“ 开始 C++
c语言·c++·学习