客户端
#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;
}