我想使用 api 在 C 中创建一个简单的多线程聊天应用程序。一开始,我编写了一个与客户端通信的简单服务器,但发送的订单消息存在问题。
示例输出:
在服务器中
*new_sock 套接字数:4
服务器:你好客户端
客户端:你好服务器
服务器:你好吗?
客户:
服务器:
在客户端
服务器:你好客户端
客户端:你好服务器
服务器:你好吗?
客户:
//server code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <pthread.h>
void* connection_handler(void* socket_descriptor)
{
int socket = *(int *)socket_descriptor;
int n;
char server_buffer[256];
memset(server_buffer, 0, sizeof(server_buffer));
printf("Server:");
gets(server_buffer);
send(socket, server_buffer, strlen(server_buffer), 0);
memset(server_buffer, 0, sizeof(server_buffer));
while ((n = recv(socket, server_buffer, 255, 0)) > 0)
{
server_buffer[n] = '\0';
printf("Client:%s\n", server_buffer);
memset(server_buffer, 0, sizeof(server_buffer));
printf("Server:");
gets(server_buffer);
send(socket, server_buffer, strlen(server_buffer), 0);
memset(server_buffer, 0, sizeof(server_buffer));
n = 0;
}
close(socket);
free(socket_descriptor);
return 0;
}
int main(int argc, char *argv[])
{
int server_sock, client_sock, portno, client_len, n;
int *new_sock;
struct sockaddr_in server_addr, client_addr;
if(argc < 2)
{
printf("ERROR: no port provided.\n");
exit(1);
}
server_sock = socket(AF_INET, SOCK_STREAM, 0);
if(server_sock < 0)
{
printf("ERROR: opening socket.");
exit(1);
}
portno = atoi(argv[1]);
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(portno);
server_addr.sin_addr.s_addr = INADDR_ANY;
if( bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0 )
{
printf("ERROR: binding socket.");
exit(1);
}
listen(server_sock, 5);
pthread_t handler_thread;
while( client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &client_len) )
{
new_sock = malloc(sizeof(int));
*new_sock = client_sock;
printf("*new_sock socket number: %d\n", *new_sock);
if( pthread_create(&handler_thread, (void *)NULL, connection_handler, (void *)new_sock) < 0)
{
printf("ERROR: creating thread\n");
exit(1);
}
}
pthread_join(handler_thread, NULL);
printf("server shut down.\n");
return 0;
}
//client code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
int main(int argc, char* argv[])
{
int sock_descriptor, portno, n;
struct sockaddr_in server_addr;
char buffer[256];
if (argc != 2)
{
printf("usage: %s port\n", argv[0]);
exit(1);
}
portno = atoi(argv[1]);
sock_descriptor = socket(AF_INET, SOCK_STREAM, 0);
if (sock_descriptor < 0)
{
printf("ERROR: creating socket!\n");
exit(1);
}
memset((char *)&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(portno);
if (connect(sock_descriptor, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
printf("ERROR: connecting server!\n");
exit(1);
}
memset(buffer, 0, sizeof(buffer));
while((n = recv(sock_descriptor, buffer, 255, 0)) > 0)
{
buffer[n] = '\0';
printf("Server:%s\n", buffer);
memset(buffer, 0, sizeof(buffer));
printf("Client:");
gets(buffer);
send(sock_descriptor, buffer, sizeof(buffer), 0);
memset(buffer, 0, sizeof(buffer));
}
if (n <= 0)
{
printf("ERROR: reading from socket");
exit(1);
}
return 0;
}
最佳答案
在线程创建后立即加入线程,accept 是一个阻塞调用(我假设您没有修改默认行为)。然而,线程分析起来很复杂,因为在 while 循环中阻塞了接受调用,所以加入的调用甚至不会到来。
while(1)
{
//do something here
...
if( pthread_create(&handler_thread, (void *)NULL, connection_handler, (void *)new_sock) < 0)
{
printf("ERROR: creating thread\n");
exit(1);
}
pthread_join(handler_thread, NULL); //Use it right after creating thread
}
关于c - C中简单套接字编程中的同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47664680/