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

客户端

cpp 复制代码
#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;
}

服务器

cpp 复制代码
#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;
}
相关推荐
Lsir10110_3 小时前
【Linux】进程信号(下半)
linux·运维·服务器
酉鬼女又兒3 小时前
零基础入门Linux指南:每天一个Linux命令_pwd
linux·运维·服务器
云飞云共享云桌面3 小时前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能
zl_dfq3 小时前
Linux 之 【多线程】(pthread_xxx、轻量级进程、原生线程库、线程ID、__thread、线程栈、线程与信号、线程与程序替换)
linux
choke2333 小时前
Python 基础语法精讲:数据类型、运算符与输入输出
java·linux·服务器
AZ996ZA3 小时前
自学linux的第二十一天【DHCP 服务从入门到实战】
linux·运维·服务器·php
_OP_CHEN3 小时前
【Linux系统编程】(二十八)深入 ELF 文件原理:从目标文件到程序加载的完整揭秘
linux·操作系统·编译·c/c++·目标文件·elf文件
Fleshy数模4 小时前
MySQL 表创建全攻略:Navicat 图形化与 Xshell 命令行双模式实践
linux·mysql
神梦流4 小时前
GE 引擎的非标准数据流处理:稀疏张量与自定义算子在图优化中的语义保持
linux·运维·服务器
.小墨迹5 小时前
apollo学习之借道超车的速度规划
linux·c++·学习·算法·ubuntu