Linux TCP 服务器实现双向通信1v1

news/2024/11/18 2:30:31/

客户端

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>char buf[250];
ssize_t recv_data;// 执行线程的函数
void* TX(void* arg) {int socket_ret = *((int*)arg);while (1) {memset(buf, 0, sizeof(buf));recv_data = recv(socket_ret, buf, sizeof(buf) - 1, 0);if (recv_data > 0) {printf("客户端发来:%s\n", buf);} else {// 处理接收数据结束或错误break;}}// 关闭客户端套接字close(socket_ret);return NULL;
}void* RX(void* arg) {int socket_ret = *((int*)arg);while (1) {printf("发送给客户端:");memset(buf, 0, sizeof(buf));fgets(buf,sizeof(buf),stdin);recv_data = send(socket_ret, buf, sizeof(buf) - 1, 0);if (recv_data > 0) {printf("发送成功\n");} else {printf("发送失败\n");break;}}// 关闭客户端套接字close(socket_ret);return NULL;
}
int main(int argc, char *argv[]){if(argc != 3){fprintf(stderr, "Usage: %s <IP> <Port>\n", argv[0]); // 修正:提供完整的错误信息exit(EXIT_FAILURE);}pthread_t thread_TX, thread_RX;struct sockaddr_in my_addr, oth_addr;int socket_ret = socket(AF_INET, SOCK_STREAM, 0);if(socket_ret < 0){perror("socket"); // 修正:提供完整的错误信息exit(EXIT_FAILURE);}memset(&my_addr, 0, sizeof(my_addr)); // 修正:使用memset替代bzeromy_addr.sin_family = AF_INET;my_addr.sin_port = htons(atoi(argv[2])); // 注意:如果atoi(argv[2])结果过大,可能会溢出my_addr.sin_addr.s_addr = inet_addr(argv[1]); // 注意:如果argv[1]不是有效的IP地址,这里会返回INADDR_NONEint connect_ret = connect(socket_ret, (const struct sockaddr *)&my_addr, sizeof(my_addr));if (connect_ret < 0){perror("connect");exit(1);}while(1){//线程int result_TX = pthread_create(&thread_TX, NULL, TX, (void*)&socket_ret);if (result_TX != 0) {perror("pthread_create for TX");close(socket_ret);continue;}int result_RX = pthread_create(&thread_RX, NULL, RX, (void*)&socket_ret);if (result_RX != 0) {perror("pthread_create for RX");close(socket_ret);pthread_join(thread_TX, NULL); // 等待TX线程结束continue;}// 等待两个线程结束pthread_join(thread_TX, NULL);pthread_join(thread_RX, NULL);// 关闭客户端套接字close(socket_ret);}return 0;
}

服务器

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>char buf[250];
ssize_t recv_data;// 执行线程的函数
void* TX(void* arg) {int client_socket = *((int*)arg);while (1) {memset(buf, 0, sizeof(buf));recv_data = recv(client_socket, buf, sizeof(buf) - 1, 0);if (recv_data > 0) {printf("客户端发来:%s\n", buf);} else {// 处理接收数据结束或错误break;}}// 关闭客户端套接字close(client_socket);return NULL;
}void* RX(void* arg) {int client_socket = *((int*)arg);while (1) {printf("发送给客户端:");memset(buf, 0, sizeof(buf));fgets(buf,sizeof(buf),stdin);recv_data = send(client_socket, buf, sizeof(buf) - 1, 0);if (recv_data > 0) {printf("发送成功\n");} else {printf("发送失败\n");break;}}// 关闭客户端套接字close(client_socket);return NULL;
}int main(int argc, char *argv[]) {if (argc != 3) {fprintf(stderr, "Usage: %s <IP> <Port>\n", argv[0]);exit(EXIT_FAILURE);}int socket_ret = socket(AF_INET, SOCK_STREAM, 0);if (socket_ret < 0) {perror("socket");exit(EXIT_FAILURE);}struct sockaddr_in my_addr, oth_addr;memset(&my_addr, 0, sizeof(my_addr));my_addr.sin_family = AF_INET;my_addr.sin_port = htons(atoi(argv[2]));my_addr.sin_addr.s_addr = inet_addr(argv[1]);if (bind(socket_ret, (const struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) {perror("bind");exit(EXIT_FAILURE);}if (listen(socket_ret, 10) < 0) {perror("listen");exit(EXIT_FAILURE);}socklen_t len = sizeof(oth_addr);pthread_t thread_TX, thread_RX;while (1) {int client_socket = accept(socket_ret, (struct sockaddr *)&oth_addr, &len);if (client_socket < 0) {perror("accept");continue;}//线程int result_TX = pthread_create(&thread_TX, NULL, TX, (void*)&client_socket);if (result_TX != 0) {perror("pthread_create for TX");close(client_socket);continue;}int result_RX = pthread_create(&thread_RX, NULL, RX, (void*)&client_socket);if (result_RX != 0) {perror("pthread_create for RX");close(client_socket);pthread_join(thread_TX, NULL); // 等待TX线程结束continue;}// 等待两个线程结束pthread_join(thread_TX, NULL);pthread_join(thread_RX, NULL);// 关闭客户端套接字close(client_socket);}// 关闭服务器套接字close(socket_ret);return 0;
}


http://www.ppmy.cn/news/1547865.html

相关文章

鸿蒙实现 web 传值

前言&#xff1a;安卓和 IOS 加载 H5 的时候&#xff0c;都有传值给到 H5 或者接收 H5 值&#xff0c;鸿蒙也可传值和接收 H5 的内容&#xff0c;以下是鸿蒙传值给 H5 端的具体操作 一: 定义好 H5 和鸿蒙传值的方法名&#xff0c;两端必须保持方法名一致 // xxx.ets import …

C语言第九周课——经典算法

目录 一、冒泡法排序 1.1原理 1.2代码实现&#xff08;以升序排序为例&#xff09; 1.3逻辑 1.4分析 二、二分法查找 2.1原理 2.2代码实现 2.3逻辑 2.4算法效率分析 三、素数判断 3.1原理 3.2代码实现 3.3逻辑 3.4分析 一、冒泡法排序 1.1原理 冒泡排序&…

【数据结构】11.哈夫曼树哈夫曼编码

一、哈夫曼树的基本概念 哈夫曼&#xff08;Huffman&#xff09;树又称最优树&#xff0c;是一类带权路径长度最短的树&#xff0c;在实际中有广泛的用途。 路径&#xff1a; 从树中一个节点到另一个节点之间的分支构成这两个节点之间的路径。路径长度&#xff1a; 路径上的分…

【泛型 Plus】Kotlin 的加强版类型推断:@BuilderInference

视频先行 下面是视频内容的脚本文案原稿分享。 小剧场 面试官&#xff1a;「既然协程和泛型你都熟悉&#xff0c;flow() 函数是怎么实现类型推断的有了解过吗&#xff1f;」 求职者&#xff1a;「嗯……」 求职者&#xff1a;「嗯……在Kotlin协程中&#xff0c;flow 是一种构建…

ScreenAgent CogAgent 安装日志

环境&#xff1a;python3.10 、conda 4.5.11 python ./cogagent_model_worker.py --host 0.0.0.0 --port 40000 --from_pretrained "saved_models/cogagent-chat" --bf16 --max_length 2048 报错&#xff1a; [2024-11-16 18:23:52,527] [INFO] [real_accelerato…

RHCE的学习(17)

shell特性回顾 1.echo linux打印命令 参数 -n 取消输出后行末的换行符号-e 支持反斜线控制的字符转换 \n \t ! 控制字符作 用\输出\本身 !\a输出警告音\b退格键&#xff0c;也就是向左删除键\c取消输出行末的换行符。和“-n”选项一致\eEsc键向右删除键\f换页符\n换行符\r字…

聊天服务器(7)数据模块

目录 Mysql数据库代码封装头文件与源文件 Mysql数据库代码封装 业务层代码不要直接写数据库&#xff0c;因为业务层和数据层的代码逻辑也想完全区分开。万一不想存储mysql&#xff0c;想存redis的话&#xff0c;就要改动大量业务代码。解耦合就是改起来很方便。 首先需要安装m…

FPGA使用Verilog实现CAN通信

FPGA实现CAN通信&#xff08;Verilog&#xff09; 1.作者使用的方法是通过FPGA芯片&#xff08;如Xilinx公司的型号为XC7K325TFFG676-2&#xff09;控制SJA1000T芯片&#xff08;CAN控制器芯片&#xff09;实现CAN通信&#xff0c;如下图所示&#xff1a; 2.熟悉连接方式之后&…