常州市网站建设,wordpress屏蔽远程头像,WordPress侧滑手机菜单,网站建站公司广州本文介绍如何使用C编写一个基本的客户端-服务端通信系统。通过这个例子#xff0c;你将学到如何建立TCP连接、发送和接收消息#xff0c;以及如何处理多个客户端连接。
客户端代码#xff1a;
#include stdio.h // 标准输入输出库#xff0c;提供基本的输入…本文介绍如何使用C编写一个基本的客户端-服务端通信系统。通过这个例子你将学到如何建立TCP连接、发送和接收消息以及如何处理多个客户端连接。
客户端代码
#include stdio.h // 标准输入输出库提供基本的输入输出功能
#include stdlib.h // 标准库包含了一些通用的函数和动态内存分配函数
#include string.h // 字符串处理库提供字符串操作的各种函数
#include unistd.h // Linux系统调用接口包含了一些常用的系统调用函数
#include arpa/inet.h // 提供了一些函数用于对IPv4和IPv6地址进行转换
#include errno.h // 用于获取错误码提供 perror 函数来输出错误信息int main(int argc, char *argv[]) {if (argc ! 4) {fprintf(stderr, Usage: %s server_ip server_port message\n, argv[0]);return EXIT_FAILURE;}int sockfd;struct sockaddr_in servaddr;// 创建套接字if ((sockfd socket(AF_INET, SOCK_STREAM, 0)) 0) {perror(create socket error);return EXIT_FAILURE;}// 初始化服务器地址结构体memset(servaddr, 0, sizeof(servaddr));servaddr.sin_family AF_INET;servaddr.sin_port htons(atoi(argv[2])); // 将端口号从字符串转换为整数// 将IP地址从字符串转换为网络地址if (inet_pton(AF_INET, argv[1], servaddr.sin_addr) 0) {perror(inet_pton error);close(sockfd);return EXIT_FAILURE;}// 发起连接请求if (connect(sockfd, (struct sockaddr*)servaddr, sizeof(servaddr)) 0) {perror(connect error);close(sockfd);return EXIT_FAILURE;}printf(Connected to the server. Sending message: %s\n, argv[3]);// 发送消息到服务器if (send(sockfd, argv[3], strlen(argv[3]), 0) 0) {perror(send error);close(sockfd);return EXIT_FAILURE;}// 接收服务器的响应char buffer[1024];ssize_t recv_len recv(sockfd, buffer, sizeof(buffer), 0);if (recv_len 0) {perror(recv error);close(sockfd);return EXIT_FAILURE;} else if (recv_len 0) {printf(Connection closed by the server\n);} else {buffer[recv_len] \0;printf(Received from server: %s\n, buffer);}// 关闭套接字close(sockfd);return EXIT_SUCCESS;
}
服务端代码
#include iostream // 输入输出流库提供了输入输出的各种功能
#include cstring // 字符串处理库提供了字符串操作的各种函数
#include thread // 多线程支持库用于创建和管理线程
#include vector // 动态数组容器提供了对动态数组的支持
#include mutex // 互斥锁库提供了对互斥锁的支持
#include queue // 队列容器提供了对队列的支持
#include netinet/in.h // 网络编程库包含了与网络相关的数据结构和函数
#include unistd.h // Linux系统调用接口包含了一些常用的系统调用函数const int MAXBUFF 1024;std::mutex g_mx; // 用于保护共享资源的互斥锁
std::queuestd::pairint, std::string g_dataQue; // 存储客户端套接字和消息的队列// 在单独的线程中处理从客户端接收到的消息
void writeThread() {while (true) {g_mx.lock(); // 上锁以确保安全访问共享资源if (!g_dataQue.empty()) {int clientFd g_dataQue.front().first;std::string data g_dataQue.front().second;std::cout 从客户端接收到的消息 data std::endl;// 假设有一个处理消息并返回响应的函数std::string response Server response: 你好客户端;send(clientFd, response.c_str(), response.size(), 0);g_dataQue.pop(); // 从队列中移除已处理的消息}g_mx.unlock(); // 解锁}
}int main() {int listenFd, clientFd;struct sockaddr_in servaddr;if ((listenFd socket(AF_INET, SOCK_STREAM, 0)) 0) {std::cerr 创建套接字错误 std::endl;return -1;}memset(servaddr, 0, sizeof(servaddr));servaddr.sin_family AF_INET;servaddr.sin_addr.s_addr htonl(INADDR_ANY);servaddr.sin_port htons(1121);if (bind(listenFd, (struct sockaddr *)servaddr, sizeof(servaddr)) 0) {std::cerr 绑定套接字地址和端口错误 std::endl;return -1;}if (listen(listenFd, 10) 0) {std::cerr 开启监听错误 std::endl;return -1;}std::thread write_thread(writeThread); // 创建一个线程来处理从客户端接收到的消息size_t readLen 0;while (true) {struct sockaddr_in client_addr;socklen_t size sizeof(client_addr);if ((clientFd accept(listenFd, (struct sockaddr *)client_addr, size)) 0) {std::cerr 建立连接错误 std::endl;return -1;}// 假设有一个读取函数来从 clientFd 中读取数据char buff[MAXBUFF] {0};readLen read(clientFd, buff, MAXBUFF);if (readLen 0) {close(clientFd); // 在读取到数据后关闭客户端连接break;}std::string data(buff, readLen);g_mx.lock(); // 上锁以确保安全访问共享资源g_dataQue.push(std::make_pair(clientFd, data)); // 将接收到的消息和客户端套接字放入队列g_mx.unlock(); // 解锁}write_thread.join(); // 等待写线程结束close(listenFd);return 0;
}
客户端使用方法
打开终端进入客户端代码所在的目录。使用以下命令运行客户端程序
gcc client.cpp -o client
./client server_ip server_port message
替换 server_ip、server_port 和 message 分别为服务器的IP地址、端口号和要发送的消息。
服务端使用方法
打开终端进入服务端代码所在的目录。使用以下命令编译并运行服务端程序
g server.cpp -o server -lpthread
./server
服务端将开始监听连接。
主要功能
客户端
接受命令行参数包括服务器IP、端口号和要发送的消息。创建套接字连接到服务器。发送消息到服务器接收并打印服务器的响应。 客户端界面 Connected to the server. Sending message: 你好服务器 Received from server: Server response: 你好客户端 服务端
创建套接字绑定地址和端口开始监听。接受客户端连接将客户端套接字和消息放入队列。在单独的线程中处理队列中的消息发送响应到客户端。 服务端界面 从客户端接收到的消息你好服务器 注意事项
通过互斥锁保护共享资源确保线程安全的访问。在服务端中处理客户端消息后返回一个固定的响应。
结论
通过这个简单的例子你学到了如何使用C创建一个基本的客户端-服务端通信系统。这是一个基础框架可以根据实际需求进行扩展和改进用于构建更复杂的网络应用。