用c编程向所有客户发送消息
sent a message to all clients with c programming
İ 正在尝试进行聊天 program.Server 将收到一条消息,然后发送给所有其他客户端。
收到来自 client.But 的消息时没有问题 SendToAll 功能不起作用。
感谢您的帮助
服务器
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 7777
#define SIZE 1024
struct clients{
struct sockaddr_in clientAddr;
struct clients *next;
};
struct clients *AddClient(struct sockaddr_in new_ClientAddr,struct clients *head)
{
struct clients *temp = head;
puts("burda2");
int a = 1;
if(head == NULL)
{
temp = (struct clients *)malloc(sizeof(struct clients));
temp->clientAddr = new_ClientAddr;
temp->next = NULL;
}
else
{
while(temp != NULL)
{
if(temp->clientAddr.sin_addr.s_addr == new_ClientAddr.sin_addr.s_addr)
{
a = 0;
break;
}
temp = temp->next;
}
if(a == 1)
{
temp->next = (struct clients *)malloc(sizeof(struct clients));
temp->next->clientAddr = new_ClientAddr;
temp = temp->next;
temp->next = NULL;
}
else{
puts("Its already save");
}
}
return head;
}
// --- End of Function AddClient() ---
void SendToAll(char msg[1023], struct sockaddr_in repliedClient, struct clients *head)
{
struct clients *temp = head;
int clients_socket;
int byte;
clients_socket = socket(AF_INET, SOCK_STREAM, 0);
if(clients_socket == -1)
perror("Error On Socket(SendToAll)");
while(temp != NULL)
{
if(repliedClient.sin_addr.s_addr != temp->clientAddr.sin_addr.s_addr)//Dont send msg who to replied
{
if(connect(clients_socket, (struct sockaddr *)&temp->clientAddr,
sizeof(struct sockaddr)) == -1)
{
perror("Error on Connect(SendToAll)");
byte = send(clients_socket, msg, strlen(msg), 0);
printf("%s message send",msg);
if(byte == -1)
perror("Error on Send(SendToAll");
else if(byte == 0)
printf("Connection've been closed");
temp = temp->next;
}
}
}
}
// --- End of Function SendToAll() ---
int main(int argc, char *argv[])
{
struct clients *head = NULL;
int socket_fd, temp_fd;
struct sockaddr_in serverAddr,new_clientAddr;
int structSize,byte;
char text[1023];
// Creating socket
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd == -1)
perror("Error on Soket");
// Editting Server socket
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = INADDR_ANY;
memset(&(serverAddr.sin_zero), '[=10=]', 8);
// Bind
if(bind(socket_fd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1)
perror("Error on Bind");
// Start listen the port
if(listen(socket_fd, 20) == -1 )
perror("Error on Listen");
structSize = sizeof(new_clientAddr);
while(1)
{
puts(" ");
// Accept
temp_fd = accept(socket_fd , (struct sockaddr *)&new_clientAddr, &structSize);
if(temp_fd == -1)
perror("Error on Accept");
// Recv
byte = recv(temp_fd, &text, SIZE-1, 0);
if(byte == -1)
perror("Error on Recv");
else if(byte == 0)
printf("Connection is close\n");
printf("%s", text);
//Add to list
head = AddClient(new_clientAddr, head);
//Send message to other clients
SendToAll(text, new_clientAddr, head);
close(temp_fd);
}
close(socket_fd);
return (EXIT_SUCCESS);
}
CLİENT
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
//#define ServerIP "35.162.226.229"
#define ServerIP "127.0.0.1"
#define ServerPort 7777
#define SIZE 1024
int main(int argc, char** argv) {
int socket_fd;
struct sockaddr_in serverAddr;
char text[SIZE],msg[SIZE-20], name[20]text temizlendi,get_msg[1024];
int byte;
// Nick
printf("Please enter your nick");
scanf("%s",name);
//Create Socket
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd == -1)
perror("Error on Socket");
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(ServerPort);
serverAddr.sin_addr.s_addr =inet_addr(ServerIP);
memset(&(serverAddr.sin_zero), '[=11=]', 8);
// Connect to server
if(connect(socket_fd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1)
perror("Error on Connect");
puts("Connected");
while(1)
{
//Get message
printf(">>>"); scanf("%s",msg);
//Edit message
strcpy(text, name);
strcat(text, " : ");
strcat(text, msg);
//Send message
byte = send(socket_fd, text, strlen(text), 0);
if(byte == -1)
perror("Error on Send");
else if(byte == 0)
printf("Connection've been closed");
//Get reply to other users
recv(socket_fd, &get_msg, SIZE-1, 0);
printf("Getting message %s", get_msg);
}
//Close socket
close(socket_fd);
return (EXIT_SUCCESS);
}
当你打开一个 SOCK_STREAM 连接时,它是双向的并且一直打开(除非你终止它或超时或类似的事情)。
如果您想向所有连接的客户端发送消息,请创建一个遍历全局客户端结构的循环。
struct clients{
struct sockaddr_in clientAddr;
struct clients *next;
};
并对每个客户端 ID 执行 send()
操作。
要使 connect()
在另一端成功(如果从服务器执行则在客户端执行)必须有一个套接字侦听器。即由 listen()
.
完成
简而言之,您不能从服务器端执行此操作。
此外,要制作聊天服务器,您的服务器代码需要执行称为 I/O 多路复用的操作。您编写的代码不会那样做,即您使用的 accept()
是阻塞调用。
服务器将执行两项主要任务
- 接受连接并跟踪连接
- 从连接的客户端接收消息并将其广播给所有其他客户端。
这两个操作应该是非阻塞的。因此,您还需要线程/多个进程来并行 运行 这些任务。
希望对您有所帮助。
İ 正在尝试进行聊天 program.Server 将收到一条消息,然后发送给所有其他客户端。
收到来自 client.But 的消息时没有问题 SendToAll 功能不起作用。
感谢您的帮助
服务器
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 7777
#define SIZE 1024
struct clients{
struct sockaddr_in clientAddr;
struct clients *next;
};
struct clients *AddClient(struct sockaddr_in new_ClientAddr,struct clients *head)
{
struct clients *temp = head;
puts("burda2");
int a = 1;
if(head == NULL)
{
temp = (struct clients *)malloc(sizeof(struct clients));
temp->clientAddr = new_ClientAddr;
temp->next = NULL;
}
else
{
while(temp != NULL)
{
if(temp->clientAddr.sin_addr.s_addr == new_ClientAddr.sin_addr.s_addr)
{
a = 0;
break;
}
temp = temp->next;
}
if(a == 1)
{
temp->next = (struct clients *)malloc(sizeof(struct clients));
temp->next->clientAddr = new_ClientAddr;
temp = temp->next;
temp->next = NULL;
}
else{
puts("Its already save");
}
}
return head;
}
// --- End of Function AddClient() ---
void SendToAll(char msg[1023], struct sockaddr_in repliedClient, struct clients *head)
{
struct clients *temp = head;
int clients_socket;
int byte;
clients_socket = socket(AF_INET, SOCK_STREAM, 0);
if(clients_socket == -1)
perror("Error On Socket(SendToAll)");
while(temp != NULL)
{
if(repliedClient.sin_addr.s_addr != temp->clientAddr.sin_addr.s_addr)//Dont send msg who to replied
{
if(connect(clients_socket, (struct sockaddr *)&temp->clientAddr,
sizeof(struct sockaddr)) == -1)
{
perror("Error on Connect(SendToAll)");
byte = send(clients_socket, msg, strlen(msg), 0);
printf("%s message send",msg);
if(byte == -1)
perror("Error on Send(SendToAll");
else if(byte == 0)
printf("Connection've been closed");
temp = temp->next;
}
}
}
}
// --- End of Function SendToAll() ---
int main(int argc, char *argv[])
{
struct clients *head = NULL;
int socket_fd, temp_fd;
struct sockaddr_in serverAddr,new_clientAddr;
int structSize,byte;
char text[1023];
// Creating socket
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd == -1)
perror("Error on Soket");
// Editting Server socket
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = INADDR_ANY;
memset(&(serverAddr.sin_zero), '[=10=]', 8);
// Bind
if(bind(socket_fd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1)
perror("Error on Bind");
// Start listen the port
if(listen(socket_fd, 20) == -1 )
perror("Error on Listen");
structSize = sizeof(new_clientAddr);
while(1)
{
puts(" ");
// Accept
temp_fd = accept(socket_fd , (struct sockaddr *)&new_clientAddr, &structSize);
if(temp_fd == -1)
perror("Error on Accept");
// Recv
byte = recv(temp_fd, &text, SIZE-1, 0);
if(byte == -1)
perror("Error on Recv");
else if(byte == 0)
printf("Connection is close\n");
printf("%s", text);
//Add to list
head = AddClient(new_clientAddr, head);
//Send message to other clients
SendToAll(text, new_clientAddr, head);
close(temp_fd);
}
close(socket_fd);
return (EXIT_SUCCESS);
}
CLİENT
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
//#define ServerIP "35.162.226.229"
#define ServerIP "127.0.0.1"
#define ServerPort 7777
#define SIZE 1024
int main(int argc, char** argv) {
int socket_fd;
struct sockaddr_in serverAddr;
char text[SIZE],msg[SIZE-20], name[20]text temizlendi,get_msg[1024];
int byte;
// Nick
printf("Please enter your nick");
scanf("%s",name);
//Create Socket
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if(socket_fd == -1)
perror("Error on Socket");
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(ServerPort);
serverAddr.sin_addr.s_addr =inet_addr(ServerIP);
memset(&(serverAddr.sin_zero), '[=11=]', 8);
// Connect to server
if(connect(socket_fd, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1)
perror("Error on Connect");
puts("Connected");
while(1)
{
//Get message
printf(">>>"); scanf("%s",msg);
//Edit message
strcpy(text, name);
strcat(text, " : ");
strcat(text, msg);
//Send message
byte = send(socket_fd, text, strlen(text), 0);
if(byte == -1)
perror("Error on Send");
else if(byte == 0)
printf("Connection've been closed");
//Get reply to other users
recv(socket_fd, &get_msg, SIZE-1, 0);
printf("Getting message %s", get_msg);
}
//Close socket
close(socket_fd);
return (EXIT_SUCCESS);
}
当你打开一个 SOCK_STREAM 连接时,它是双向的并且一直打开(除非你终止它或超时或类似的事情)。
如果您想向所有连接的客户端发送消息,请创建一个遍历全局客户端结构的循环。
struct clients{
struct sockaddr_in clientAddr;
struct clients *next;
};
并对每个客户端 ID 执行 send()
操作。
要使 connect()
在另一端成功(如果从服务器执行则在客户端执行)必须有一个套接字侦听器。即由 listen()
.
简而言之,您不能从服务器端执行此操作。
此外,要制作聊天服务器,您的服务器代码需要执行称为 I/O 多路复用的操作。您编写的代码不会那样做,即您使用的 accept()
是阻塞调用。
服务器将执行两项主要任务
- 接受连接并跟踪连接
- 从连接的客户端接收消息并将其广播给所有其他客户端。
这两个操作应该是非阻塞的。因此,您还需要线程/多个进程来并行 运行 这些任务。
希望对您有所帮助。