Ich habe einen einfachen Server und Client C-Code, um einen Chatroom für Multiclients mit Threads (Pthread-Bibliothek) zu tun. Das Problem, das ich hatte, ist, dass ich keine Möglichkeit finde, den Server dazu zu bringen, jede Nachricht zu schreiben, die ein Client über den Socket an alle anderen Clients sendet. Ich habe andere ähnliche Beiträge hier gelesen und es war hilflos. Bitte helfen Sie mir, ich muss das für die Schule tun. Ich werde beide Codes sofort senden.Chatroom in C/Socket-Programmierung unter Linux
server.c:
#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
void *connection_handler(void *);
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c , *new_sock;
struct sockaddr_in server , client;
char *message;
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(8888);
//Bind
if(bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
while((new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)))
{
puts("Connection accepted");
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = new_socket;
if(pthread_create(&sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)
{
perror("could not create thread");
return 1;
}
//Now join the thread , so that we dont terminate before the thread
//pthread_join(sniffer_thread , NULL);
puts("Handler assigned");
}
if (new_socket<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 read_size;
char *message , client_message[2000];
//Receive a message from client
while((read_size = recv(sock , client_message , 2000 , 0)) > 0)
{
//Send the message back to client
write(sock , client_message , strlen(client_message));
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
//Free the socket pointer
free(socket_desc);
return 0;
}
client.c
#include<stdio.h> //printf
#include<string.h> //strlen
#include<sys/socket.h> //socket
#include<arpa/inet.h> //inet_addr
int main(int argc , char *argv[])
{
int sock;
struct sockaddr_in server;
char message[1000] , server_reply[2000];
//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(8888);
//Connect to remote server
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return 1;
}
puts("Connected\n");
puts("Bienvenido al Chatroom, puedes empezar a escribir en la sala!");
//keep communicating with server
while(1)
{
printf("Enter message: ");
fgets(message, sizeof(message),stdin);
//scanf("%s" , message);
//Send some data
if(send(sock , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
//Receive a reply from the server
if(recv(sock , server_reply , 2000 , 0) < 0)
{
puts("recv failed");
break;
}
printf("Server Reply: %s\n", server_reply);
server_reply[0]='\0';
}
close(sock);
return 0;
}
Diese Programme sind sehr einfach, sendet der Client, was der Benutzer in der Konsole schreibt, und der Server die gleiche Nachricht zurückschicken. Ich brauche nur den Server, um dieselbe Nachricht an jeden verbundenen Thread (Client) zu senden (nicht nur an den, der die ursprüngliche Nachricht gesendet hat).
Ich weiß, das lang ist für jedermann, zu kümmern, aber wenn Sie können, ich werde froh sein, etwas Hilfe zu bekommen :)
Ist es erforderlich, dass Sie Threads dafür verwenden? Ein einfacherer Entwurf wäre single-threaded und multiplexen die E/A-Operationen mit select() oder poll(). Dann könnte das Schreiben in alle Sockets aller Clients mit einer einfachen For-Schleife erfolgen. –
Oh danke, das wird wahrscheinlich einfacher sein. Trotzdem weiß ich nicht, wie man select() oder poll() haha benutzt. Ich habe Threads verwendet, weil ich vor kurzem gelernt habe, wie man sie benutzt und sie schienen eine ziemlich pro-Lösung für mein Problem zu sein, haha. Gibt es eine Chance, dass Sie mir ein paar Details über die Verwendung dieser Funktionen geben könnten? :) –
Fäden sind starke Medizin - sie können dich beißen, wenn du nicht sehr vorsichtig bist. Ich versuche, sie nicht zu benutzen, es sei denn, es gibt keinen anderen Weg, diese Aufgabe zu erfüllen. Wie für select(), siehe diese Links: http://www.lowtek.com/sockets/select.html http://www.binarytides.com/multiple-socket-connections-fdset-select-linux/ –