多个客户端可以向一个服务器发送连接请求
//客户端
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc,char**argv)
{
if(argc != 3)
{
printf("请输入IP地址和端口号\n");
return -1;
}
//创建套接字
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if(sock_fd == -1)
{
perror("创建套接字失败");
return -1;
}
//绑定
//定义结构体
struct sockaddr_in serve;
serve.sin_family = AF_INET;
serve.sin_port = htons(atoi(argv[2]));
serve.sin_addr.s_addr = inet_addr(argv[1]);
int ret = bind(sock_fd, (struct sockaddr*)&serve, sizeof(serve));
//连接对监听端套接字
int sock_con = connect(sock_fd, (struct sockaddr*)&serve, sizeof(serve));
if(sock_con == -1)
{
perror("连接失败");
return -1;
}
if(sock_con == 0)
{
printf("连接成功!\n");
}
//向 TCP 套接字发送数据
char *buf = malloc(100);
while(1)
{
memset(buf,0,100);
//发送
printf("请输入:(输入exit退出)\n");
fgets(buf, 100, stdin);
send(sock_fd, buf, 100, 0);
if (strcmp(buf, "exit\n") == 0)
{
break;
}
}
}
//服务器端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void* handle_client(void* arg)
{
int client_fd = *(int*)arg;
free(arg); // 释放之前为客户端文件描述符指针分配的内存
char buf[100]; // 直接在栈上分配,避免每次都需要malloc和free
while (1)
{
memset(buf, 0, sizeof(buf));
ssize_t bytes_received = recv(client_fd, buf, sizeof(buf) - 1, 0); // 减1以留出空间给字符串终止符
if (bytes_received == -1)
{
perror("recv failed");
break;
}
if (strcmp(buf, "exit\n") == 0)
{
printf("退出\n");
break;
}
printf("客户端: %s", buf);
}
close(client_fd);
return NULL;
}
int main(int argc, char **argv)
{
if (argc != 3)
{
printf("输入不合法!请输入IP地址和端口号!\n");
}
// 创建套接字
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd == -1)
{
perror("创建套接字失败");
return -1;
}
// 绑定服务器的IP地址+端口号
struct sockaddr_in serve;
memset(&serve,0,sizeof(serve));
serve.sin_family = AF_INET;
serve.sin_port = htons(atoi(argv[2]));
if (inet_pton(AF_INET, argv[1], &serve.sin_addr) <= 0)
{
perror("地址不合法");
close(sock_fd);
return -1;
}
// 绑定
if (bind(sock_fd, (struct sockaddr *)&serve, sizeof(serve)) == -1)
{
perror("绑定失败");
return -1;
}
// 监听
if (listen(sock_fd, 4) == -1)
{
perror("监听");
close(sock_fd);
return -1;
}
// 等待连接
printf("等待连接...\n");
pthread_t thread_id;
while (1)
{
// 无限循环以接受新的连接
int acc_fd = accept(sock_fd, NULL, NULL);
if (acc_fd == -1)
{
perror("连接");
continue;
}
printf("连接成功\n");
// 为新的连接创建一个新的线程
int *client_fd_ptr = malloc(sizeof(int));
if (!client_fd_ptr)
{
perror("malloc failed for client_fd_ptr");
close(acc_fd);
continue;
}
*client_fd_ptr = acc_fd;
if (pthread_create(&thread_id, NULL, handle_client, client_fd_ptr) != 0)
{
perror("pthread_create failed");
free(client_fd_ptr);
close(acc_fd);
continue;
}
}
}