在 c 中使用 TCP 的多用户聊天服务器。如何向多个客户端发送数据?
multi user chat server using TCP in c. How to send data to multiple clients?
我想在 C 中使用 TCP 创建一个多用户聊天服务器,当客户端向服务器发送消息时。它将发送给所有其他客户端。
我找不到任何向多个客户端发送数据的方法,是否有某种方法可以遍历连接到套接字的所有客户端,或者是否有某种方法可以向所有客户端广播消息。
这是我的代码
server.c
#include <stdio.h>
#include <sys/socket.h> //for sock()
#include <string.h>//for using memset
#include <arpa/inet.h>// for inet_addr()
#include <unistd.h>//for using write() function
int main(){
int sock=0, client_conn=0,counter=0,pid;
char data_send[1024],data_received[1024];
struct sockaddr_in ServerIp;
sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&ServerIp,'0',sizeof(ServerIp) );
ServerIp.sin_family = AF_INET;
ServerIp.sin_port = htons(1234);
ServerIp.sin_addr . s_addr = inet_addr("127.0.0.1");
if( bind( sock,(struct sockaddr* )&ServerIp, sizeof(ServerIp)) == -1 )
printf("\n Socket binding failed ");
if( listen(sock,20) == -1)
printf("Error\n");
else
printf("\n Server started\n");
for(;;){
label:
client_conn = accept( sock, (struct sockaddr*)NULL, NULL);
pid = fork();
if( pid < 0 )
printf("\n Process creation failed ");
else if( pid > 0 ){
counter++;
///close(client_conn);
goto label;
}
else{
counter++;
if( recv(client_conn, data_received, 1024, 0 ) == -1 )
printf(" Error !! cannot get response \n");
printf(" data from client is %s\n",data_received);
sprintf(data_send," Hi client %d !! from server ",counter);
write( client_conn, data_send, sizeof(data_send) );
}
}
close( sock );
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h> //for sock()
#include <string.h>//for using memset
#include <arpa/inet.h>// for inet_addr()
#include <unistd.h>//for using write() function
int main(){
enter code here
char data_received[1024],data_send[1024];
int sock=0;
struct sockaddr_in ServerIp;
if( (sock = socket(AF_INET, SOCK_STREAM ,0 )) == -1 )
printf(" socket creation failed ");
ServerIp.sin_family = AF_INET;
ServerIp.sin_port = htons(1234);
ServerIp.sin_addr . s_addr = inet_addr("127.0.0.1");
if( (connect( sock, (struct sockaddr *)&ServerIp, sizeof(ServerIp) )) == -1 ){
printf("\n connection to the socket failed ");
exit(0);
}
else
printf("\n connected to socket \n");
strcpy(data_send,"hello server");
if( send(sock,data_send,sizeof(data_send),0) == -1 )
printf("sending failed ");
while(1){
printf("\n waiting for respose !! \n");
if( recv(sock, data_received, 1024, 0 ) == -1 )
printf(" Error !! cannot get response |n");
else
printf("\n Response Received is : %s", data_received );
}
}
有什么建议吗??
广播是通过更新所有已连接客户端及其文件描述符的列表,并遍历它以向每个客户端发送消息来完成的(您不能像在 UDP 中那样在 TCP 中进行广播因为 TCP 是连接协议而 UDP 不是)。
如果它有任何用处,这里是我用 C 语言为学校项目制作的多用户 TCP 服务器的回购:https://github.com/DatPenguin/TCPServer。不是聊天,但是TCP部分应该是一样的。
在client
文件夹中是客户端的代码,而服务器端在server
文件夹中。
我找到了一种使用 pthread 来实现的简单易行的方法。这是代码
服务器代码
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
pthread_mutex_t mutex;
int clients[20];
int n=0;
void sendtoall(char *msg,int curr){
int i;
pthread_mutex_lock(&mutex);
for(i = 0; i < n; i++) {
if(clients[i] != curr) {
if(send(clients[i],msg,strlen(msg),0) < 0) {
printf("sending failure \n");
continue;
}
}
}
pthread_mutex_unlock(&mutex);
}
void *recvmg(void *client_sock){
int sock = *((int *)client_sock);
char msg[500];
int len;
while((len = recv(sock,msg,500,0)) > 0) {
msg[len] = '[=10=]';
sendtoall(msg,sock);
}
}
int main(){
struct sockaddr_in ServerIp;
pthread_t recvt;
int sock=0 , Client_sock=0;
ServerIp.sin_family = AF_INET;
ServerIp.sin_port = htons(1234);
ServerIp.sin_addr.s_addr = inet_addr("127.0.0.1");
sock = socket( AF_INET , SOCK_STREAM, 0 );
if( bind( sock, (struct sockaddr *)&ServerIp, sizeof(ServerIp)) == -1 )
printf("cannot bind, error!! \n");
else
printf("Server Started\n");
if( listen( sock ,20 ) == -1 )
printf("listening failed \n");
while(1){
if( (Client_sock = accept(sock, (struct sockaddr *)NULL,NULL)) < 0 )
printf("accept failed \n");
pthread_mutex_lock(&mutex);
clients[n]= Client_sock;
n++;
// creating a thread for each client
pthread_create(&recvt,NULL,(void *)recvmg,&Client_sock);
pthread_mutex_unlock(&mutex);
}
return 0;
}
客户代码
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
char msg[500];
void *recvmg(void *my_sock)
{
int sock = *((int *)my_sock);
int len;
// client thread always ready to receive message
while((len = recv(sock,msg,500,0)) > 0) {
msg[len] = '[=11=]';
fputs(msg,stdout);
}
}
int main(int argc,char *argv[]){
pthread_t recvt;
int len;
int sock;
char send_msg[500];
struct sockaddr_in ServerIp;
char client_name[100];
strcpy(client_name, argv[1]);
sock = socket( AF_INET, SOCK_STREAM,0);
ServerIp.sin_port = htons(1234);
ServerIp.sin_family= AF_INET;
ServerIp.sin_addr.s_addr = inet_addr("127.0.0.1");
if( (connect( sock ,(struct sockaddr *)&ServerIp,sizeof(ServerIp))) == -1 )
printf("\n connection to socket failed \n");
//creating a client thread which is always waiting for a message
pthread_create(&recvt,NULL,(void *)recvmg,&sock);
//ready to read a message from console
while(fgets(msg,500,stdin) > 0) {
strcpy(send_msg,client_name);
strcat(send_msg,":");
strcat(send_msg,msg);
len = write(sock,send_msg,strlen(send_msg));
if(len < 0)
printf("\n message not sent \n");
}
//thread is closed
pthread_join(recvt,NULL);
close(sock);
return 0;
}
要查看输出,请参阅 https://codingile.wordpress.com/multiuser-chat-server-in-c/
我想在 C 中使用 TCP 创建一个多用户聊天服务器,当客户端向服务器发送消息时。它将发送给所有其他客户端。
我找不到任何向多个客户端发送数据的方法,是否有某种方法可以遍历连接到套接字的所有客户端,或者是否有某种方法可以向所有客户端广播消息。
这是我的代码
server.c
#include <stdio.h>
#include <sys/socket.h> //for sock()
#include <string.h>//for using memset
#include <arpa/inet.h>// for inet_addr()
#include <unistd.h>//for using write() function
int main(){
int sock=0, client_conn=0,counter=0,pid;
char data_send[1024],data_received[1024];
struct sockaddr_in ServerIp;
sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&ServerIp,'0',sizeof(ServerIp) );
ServerIp.sin_family = AF_INET;
ServerIp.sin_port = htons(1234);
ServerIp.sin_addr . s_addr = inet_addr("127.0.0.1");
if( bind( sock,(struct sockaddr* )&ServerIp, sizeof(ServerIp)) == -1 )
printf("\n Socket binding failed ");
if( listen(sock,20) == -1)
printf("Error\n");
else
printf("\n Server started\n");
for(;;){
label:
client_conn = accept( sock, (struct sockaddr*)NULL, NULL);
pid = fork();
if( pid < 0 )
printf("\n Process creation failed ");
else if( pid > 0 ){
counter++;
///close(client_conn);
goto label;
}
else{
counter++;
if( recv(client_conn, data_received, 1024, 0 ) == -1 )
printf(" Error !! cannot get response \n");
printf(" data from client is %s\n",data_received);
sprintf(data_send," Hi client %d !! from server ",counter);
write( client_conn, data_send, sizeof(data_send) );
}
}
close( sock );
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h> //for sock()
#include <string.h>//for using memset
#include <arpa/inet.h>// for inet_addr()
#include <unistd.h>//for using write() function
int main(){
enter code here
char data_received[1024],data_send[1024];
int sock=0;
struct sockaddr_in ServerIp;
if( (sock = socket(AF_INET, SOCK_STREAM ,0 )) == -1 )
printf(" socket creation failed ");
ServerIp.sin_family = AF_INET;
ServerIp.sin_port = htons(1234);
ServerIp.sin_addr . s_addr = inet_addr("127.0.0.1");
if( (connect( sock, (struct sockaddr *)&ServerIp, sizeof(ServerIp) )) == -1 ){
printf("\n connection to the socket failed ");
exit(0);
}
else
printf("\n connected to socket \n");
strcpy(data_send,"hello server");
if( send(sock,data_send,sizeof(data_send),0) == -1 )
printf("sending failed ");
while(1){
printf("\n waiting for respose !! \n");
if( recv(sock, data_received, 1024, 0 ) == -1 )
printf(" Error !! cannot get response |n");
else
printf("\n Response Received is : %s", data_received );
}
}
有什么建议吗??
广播是通过更新所有已连接客户端及其文件描述符的列表,并遍历它以向每个客户端发送消息来完成的(您不能像在 UDP 中那样在 TCP 中进行广播因为 TCP 是连接协议而 UDP 不是)。
如果它有任何用处,这里是我用 C 语言为学校项目制作的多用户 TCP 服务器的回购:https://github.com/DatPenguin/TCPServer。不是聊天,但是TCP部分应该是一样的。
在client
文件夹中是客户端的代码,而服务器端在server
文件夹中。
我找到了一种使用 pthread 来实现的简单易行的方法。这是代码
服务器代码
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <pthread.h>
pthread_mutex_t mutex;
int clients[20];
int n=0;
void sendtoall(char *msg,int curr){
int i;
pthread_mutex_lock(&mutex);
for(i = 0; i < n; i++) {
if(clients[i] != curr) {
if(send(clients[i],msg,strlen(msg),0) < 0) {
printf("sending failure \n");
continue;
}
}
}
pthread_mutex_unlock(&mutex);
}
void *recvmg(void *client_sock){
int sock = *((int *)client_sock);
char msg[500];
int len;
while((len = recv(sock,msg,500,0)) > 0) {
msg[len] = '[=10=]';
sendtoall(msg,sock);
}
}
int main(){
struct sockaddr_in ServerIp;
pthread_t recvt;
int sock=0 , Client_sock=0;
ServerIp.sin_family = AF_INET;
ServerIp.sin_port = htons(1234);
ServerIp.sin_addr.s_addr = inet_addr("127.0.0.1");
sock = socket( AF_INET , SOCK_STREAM, 0 );
if( bind( sock, (struct sockaddr *)&ServerIp, sizeof(ServerIp)) == -1 )
printf("cannot bind, error!! \n");
else
printf("Server Started\n");
if( listen( sock ,20 ) == -1 )
printf("listening failed \n");
while(1){
if( (Client_sock = accept(sock, (struct sockaddr *)NULL,NULL)) < 0 )
printf("accept failed \n");
pthread_mutex_lock(&mutex);
clients[n]= Client_sock;
n++;
// creating a thread for each client
pthread_create(&recvt,NULL,(void *)recvmg,&Client_sock);
pthread_mutex_unlock(&mutex);
}
return 0;
}
客户代码
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>
char msg[500];
void *recvmg(void *my_sock)
{
int sock = *((int *)my_sock);
int len;
// client thread always ready to receive message
while((len = recv(sock,msg,500,0)) > 0) {
msg[len] = '[=11=]';
fputs(msg,stdout);
}
}
int main(int argc,char *argv[]){
pthread_t recvt;
int len;
int sock;
char send_msg[500];
struct sockaddr_in ServerIp;
char client_name[100];
strcpy(client_name, argv[1]);
sock = socket( AF_INET, SOCK_STREAM,0);
ServerIp.sin_port = htons(1234);
ServerIp.sin_family= AF_INET;
ServerIp.sin_addr.s_addr = inet_addr("127.0.0.1");
if( (connect( sock ,(struct sockaddr *)&ServerIp,sizeof(ServerIp))) == -1 )
printf("\n connection to socket failed \n");
//creating a client thread which is always waiting for a message
pthread_create(&recvt,NULL,(void *)recvmg,&sock);
//ready to read a message from console
while(fgets(msg,500,stdin) > 0) {
strcpy(send_msg,client_name);
strcat(send_msg,":");
strcat(send_msg,msg);
len = write(sock,send_msg,strlen(send_msg));
if(len < 0)
printf("\n message not sent \n");
}
//thread is closed
pthread_join(recvt,NULL);
close(sock);
return 0;
}
要查看输出,请参阅 https://codingile.wordpress.com/multiuser-chat-server-in-c/