【发布时间】:2026-01-17 21:00:01
【问题描述】:
我刚刚开始学习基本的网络概念。我正在尝试在 C 中实现多线程服务器-客户端程序。但问题是不是为客户端运行多个窗口/终端/实例,我应该使用 fork() 来创建client.so 通过创建客户端的子级,将创建多个客户端。现在这些子客户端中的每一个都将在线程上与服务器通信。
之前我创建了一个类似的程序,但是对于多个客户端,您必须为客户端打开多个窗口并运行所有窗口。
我在哪里修改我的代码时遇到了麻烦(在服务器和客户端代码中。我认为服务器一是好的。但我不知道在客户端程序中的哪个位置 fork() 以及应该进行哪些更改)。
实际上我不想打开多个窗口来运行多个客户端,这就是为什么我使用 fork() 创建它的多个副本。有没有其他方法可以创建多个客户端并将它们连接到我的通过线程进行服务器编程。
服务器:
// socket server example, handles multiple clients using threads
#include<stdio.h>
#include<string.h> //strlen
#include<stdlib.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<pthread.h> //for threading , link with lpthread
//the thread function
void *connection_handler(void *);
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , *new_sock;
struct sockaddr_in server , client;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 3000 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
c=sizeof(struct sockaddr_in);
while(client_sock=accept(socket_desc,(struct sockaddr*)&client,(socklen_t*)&c))
{
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
puts("Handler assigned");
}
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
return 0;
}
/*
This will handle connection for each client
*/
void *connection_handler(void *socket_desc)
{
//Get the socket descriptor
int sock = *(int*)socket_desc;
int n;
char sendBuff[100], client_message[2000];
while((n=recv(sock,client_message,2000,0))>0)
{
send(sock,client_message,n,0);
}
close(sock);
if(n==0)
{
puts("Client Disconnected");
}
else
{
perror("recv failed");
}
return 0;
}
客户:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_SIZE 50
int main()
{
int sock_desc;
struct sockaddr_in serv_addr;
char sbuff[MAX_SIZE],rbuff[MAX_SIZE];
if((sock_desc = socket(AF_INET, SOCK_STREAM, 0)) < 0)
printf("Failed creating socket\n");
bzero((char *) &serv_addr, sizeof (serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
serv_addr.sin_port = htons(3000);
if (connect(sock_desc, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
printf("Failed to connect to server\n");
return -1;
}
printf("Connected successfully - Please enter string\n");
while(fgets(sbuff, MAX_SIZE , stdin)!=NULL)
{
send(sock_desc,sbuff,strlen(sbuff),0);
if(recv(sock_desc,rbuff,MAX_SIZE,0)==0)
printf("Error");
else
fputs(rbuff,stdout);
bzero(rbuff,MAX_SIZE);//to clean buffer-->IMP otherwise previous word characters also came
}
close(sock_desc);
return 0;
}
【问题讨论】:
-
为什么要在客户端
fork()?这很不寻常 -
@Felipe:如果客户端是测试代码来模拟连接到服务器的多个客户端,这将是有意义的。
-
如果你想学习网络编程,我建议你看看比 fork 更现代的概念。调查基于线程或事件的 IO。分叉是网络程序的原始且过时的模型。
-
Filipe:这就是我的老师要求我做的。实际上我不想打开多个窗口来运行多个客户端,这就是为什么我使用 fork() 创建它的多个副本。是还有其他方法可以让我创建多个客户端并通过线程将它们连接到我的服务器 prog。
-
你忘记在 connection_handler 中释放 (socket_desc)。
标签: c multithreading tcp operating-system