当前位置: 首页 > article >正文

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

客户端

#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替代bzero
    my_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_NONE

	int 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.kler.cn/a/402422.html

相关文章:

  • 【系统架构设计师】真题论文: 论企业应用系统的数据持久层架构设计(包括解题思路和素材)
  • Go小记:使用Go实现ssh客户端
  • Golang超详细入门教程
  • android 性能分析工具(04)Asan 内存检测工具
  • ROS2 Humble 机器人建模和Gazebo仿真
  • 【H2O2|全栈】MySQL的云端部署
  • 精通Rust系统教程-过程宏入门
  • Python操作Mysql中cursor的作用
  • Jmeter中的断言(四)
  • HBase 了解
  • django启动项目报错解决办法
  • Linux配置MySQL自动备份
  • 【降噪】自适应麦克风阵列系统
  • 人工智能在医疗健康中的应用:科技如何守护生命?
  • C语言-指针及变量的概念与使用
  • 手动搭建 WordPress 个人站点(Windows)
  • 基于Java+Springboot+Jpa+Mysql实现的在线网盘文件分享系统功能设计与实现二
  • vector容器的学习
  • 解读AI智能招聘如何精准高效解决企业人才缺口
  • 【机器学习】机器学习中用到的高等数学知识-6. 组合数学 (Combinatorics)