C语言 TCP客户端
编译命令:
gcc -o a a.c -lpthread
功能:
1、每秒发送一个字符串
2、接收与发送独立线程
3、断开可自动重连
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
#define SERVER_IP "192.168.10.111" // 服务器的IP地址
#define SERVER_PORT 8080 // 服务器的端口号
#define BUFFER_SIZE 1024 // 缓冲区大小
int sockfd = -1;
pthread_mutex_t sockfd_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t thread_cond = PTHREAD_COND_INITIALIZER;
void *threadTcpSend(void* arg) {
const char *message = "Hello, Server!";
while (1) {
if (send(sockfd, message, strlen(message), 0) < 0) {
perror("Send failed");
pthread_cond_signal(&thread_cond); // 通知主线程连接可能有问题
pthread_mutex_unlock(&sockfd_mutex);
break;
}
printf("Message sent: %s\n", message);
sleep(1);
}
return NULL;
}
void *threadTcpRecv(void* arg) {
char buffer[BUFFER_SIZE] = {0};
while (1) {
int valread = read(sockfd, buffer, BUFFER_SIZE - 1);
if (valread <= 0) {
perror("Read failed");
pthread_cond_signal(&thread_cond); // 通知主线程连接可能有问题
pthread_mutex_unlock(&sockfd_mutex);
break;
}
buffer[valread] = '\0'; // 添加字符串结束符
printf("Message received: %s\n", buffer);
}
return NULL;
}
int main() {
pthread_t thread1, thread2;
struct sockaddr_in server_addr;
while(1){
// 创建套接字
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket creation failed");
sleep(3);
continue;
}
// 配置服务器地址信息
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
// 将服务器IP地址从文本转换为二进制形式
if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
perror("Invalid address/ Address not supported");
close(sockfd);
sleep(3);
continue;
}
// 连接到服务器
if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Connection Failed");
sleep(3);
continue;
}
// 创建线程
pthread_create(&thread1, NULL, threadTcpSend, NULL);
pthread_create(&thread2, NULL, threadTcpRecv, NULL);
// 等待线程通知连接问题或手动中断
pthread_mutex_lock(&sockfd_mutex);
pthread_cond_wait(&thread_cond, &sockfd_mutex);
pthread_mutex_unlock(&sockfd_mutex);
// 尝试优雅地停止线程
pthread_cancel(thread1);
pthread_cancel(thread2);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
close(sockfd);
sockfd = -1; // 标记套接字为无效
sleep(1); // 等待一段时间后重试连接
}
return 0;
}