我刚开始学习基本的网络概念。我想在C语言中实现一个多线程的服务器-客户端程序。问题是,与其为每个客户端运行多个窗口/终端/实例,我应该使用fork()来创建客户端的子进程。这样一来,将创建多个客户端。现在,每个子客户端都将在一个线程上与服务器通信。
之前我创建了类似的程序,但对于多个客户端,您必须为每个客户端打开多个窗口并同时运行所有客户端。
我不知道在哪里修改我的代码(无论是在服务器还是客户端中)。我认为服务器端没问题。但我不知道在客户端程序中应该在哪里使用fork(),以及需要进行哪些更改。
实际上,我不想打开多个窗口来运行多个客户端,这就是我使用fork()来创建多个副本的原因。是否有其他方法可以通过线程创建多个客户端,并将它们连接到我的服务器程序中。
服务器:
之前我创建了类似的程序,但对于多个客户端,您必须为每个客户端打开多个窗口并同时运行所有客户端。
我不知道在哪里修改我的代码(无论是在服务器还是客户端中)。我认为服务器端没问题。但我不知道在客户端程序中应该在哪里使用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()
?这很不寻常。 - Filipe Gonçalves