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;
}
相关推荐
Learning改变世界11 分钟前
DNS服务器Mac地址绑定与ip网路管理命令(Ubuntu24.04)
linux·服务器·网络
长安 故里19 分钟前
TiDB v7.5.4安装部署
java·linux·tidb
运维佬23 分钟前
在Linux环境下部署TiDB可以通过几种不同的方法
linux·docker·tidb
孤邑1 小时前
【Linux】Ubuntu中muduo库的编译环境安装
linux·服务器·ubuntu
yiyayi@che1 小时前
Jetson ros默认依赖opencv与系统安装opencv、推流、cv_bridge等存在BUG
linux
CodeAaron1 小时前
华为Mate 70临近上市:代理IP与抢购攻略
网络协议·tcp/ip·华为
IPdodo全球网络1 小时前
搭建高效稳定的ChatGPT网络环境:从网络专线到IP地址管理的全流程解析
网络·tcp/ip·chatgpt
java_heartLake2 小时前
网络协议之TCP
网络·网络协议·tcp/ip
დ旧言~2 小时前
【网络】网络层——IP协议
服务器·网络·网络协议·tcp/ip·php·apache
谁在夜里看海.2 小时前
【Linux】详解僵尸进程与孤儿进程(Z僵死状态引发的内存泄漏与处理办法)
linux·运维·服务器