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;
}
原文地址:https://blog.csdn.net/m0_58341340/article/details/143820284
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!