手写服务器与手写客户端相连接-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 语言服务器和客户端就成功连接并交换了消息。

相关推荐
charlie1145141912 小时前
嵌入式的现代C++教程——constexpr与设计技巧
开发语言·c++·笔记·单片机·学习·算法·嵌入式
好奇龙猫2 小时前
【AI学习-comfyUI学习-三十二节-FLXU原生态反推+controlnet depth(UNion)工作流-各个部分学习】
人工智能·学习
好奇龙猫3 小时前
【大学院-筆記試験練習:数据库(データベース問題訓練) と 软件工程(ソフトウェア)(7)】
学习
j_jiajia4 小时前
(一)人工智能算法之监督学习——KNN
人工智能·学习·算法
2301_783360134 小时前
关于RNAseq——从fastq到gene_counts全流程
笔记·学习
_李小白4 小时前
【AlohaMini学习笔记】第三天:AlohaMini相关技术
笔记·学习
我命由我123455 小时前
Photoshop - Photoshop 工具栏(57)模糊工具
学习·ui·职场和发展·求职招聘·职场发展·学习方法·photoshop
yatingliu20195 小时前
将深度学习环境迁移至老旧系统| 个人学习笔记
笔记·深度学习·学习
week_泽5 小时前
第1课:AI Agent是什么 - 学习笔记_1
人工智能·笔记·学习
开开心心_Every5 小时前
安卓后台录像APP:息屏录存片段,行车用
java·服务器·前端·学习·eclipse·edge·powerpoint