我想创建一个非阻塞聊天。
聊天的工作方式如下:Client1向服务器发送一条消息,然后服务器将其发送给其他客户端。
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#define PORT 50000
#define TRUE 1
#define FALSE 0
int main() {
pid_t pid;
int serverSocket, binding, valrecv, newSocket, client_socket[30], activity, max_clients = 30, max_sd, sd, addrlen;
struct sockaddr_in serverAddr;
char buffer[1024];
fd_set readfds;
int i;
for(i=0; i<max_clients; i++) {
client_socket[i] = 0;
}
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if(serverSocket < 0) {
printf("[-] Socket error.\n");
exit(1);
}
printf("[+] Server socket created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
binding = bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
if(binding < 0) {
printf("[-] Binding error.\n");
exit(1);
}
printf("[+] Socked binded.\n");
if(listen(serverSocket, 2) == 0) {
printf("[+] Listening...\n");
} else {
printf("[-] Listening error.\n");
}
while(TRUE) {
FD_ZERO(&readfds);
FD_SET(serverSocket, &readfds);
max_sd = serverSocket;
for(i=0; i<max_clients; i++) {
sd = client_socket[i];
if(sd > 0) {
FD_SET(sd, &readfds);
}
if(sd > max_sd) {
max_sd = sd;
}
}
activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);
if(activity < 0) {
printf("[-] Select error.\n");
}
if(FD_ISSET(serverSocket, &readfds)) {
newSocket = accept(serverSocket, (struct sockaddr*)&serverAddr, (socklen_t*)&addrlen);
if (newSocket < 0) {
printf("[-] Accept error.\n");
exit(1);
}
printf("New connection, socked fd: %d, ip: %s:%d\n",
newSocket, inet_ntoa(serverAddr.sin_addr), ntohs(serverAddr.sin_port));
if( send(newSocket, "HI", strlen("HI"), 0) != strlen("Current Board") )
{
perror("send");
}
for (i = 0; i < max_clients; i++) {
if( client_socket[i] == 0 )
{
client_socket[i] = newSocket;
printf("Adding to list of sockets as %d\n" , i);
break;
}
}
}
for (i = 0; i < max_clients; i++)
{
sd = client_socket[i];
if (FD_ISSET( sd , &readfds))
{
//Check if it was for closing , and also read the
//incoming message
if ((valrecv = recv( sd , buffer, sizeof(buffer), 0)) == 0)
{
//Somebody disconnected , get his details and print
getpeername(sd, (struct sockaddr*)&serverAddr, (socklen_t*)&addrlen);
printf("Host disconnected , ip %s , port %d \n" ,
inet_ntoa(serverAddr.sin_addr) , ntohs(serverAddr.sin_port));
//Close the socket and mark as 0 in list for reuse
close( sd );
client_socket[i] = 0;
}
//Echo back the message that came in
else
{
//set the string terminating NULL byte on the end
//of the data read
buffer[valrecv] = '\0';
int j;
for(j=0; j<max_clients; j++) {
sd = client_socket[j];
send(sd, buffer, strlen(buffer), 0);
}
}
}
}
}
return 0;
}
客户:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 50000
int main() {
int clientSocket, connection;
struct sockaddr_in serverAddr;
char buffer[1024];
clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket < 0) {
printf("[-] Socket error.\n");
exit(1);
}
printf("[+] Client socket created.\n");
memset(&serverAddr, '\0', sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(PORT);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
connection = connect(clientSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr));
if(connection < 0) {
printf("[-] Connection error.\n");
exit(1);
}
printf("[+] Connected to server.\n");
while(TRUE) {
send(clientSocket, "TEST", strlen("TEST"), MSG_DONTWAIT);
if(recv(clientSocket, buffer, 1024, 0) < 0) {
printf("[-] Data receiving error.\n");
} else {
printf("Server: %s\n", buffer);
}
}
return 0;
}
在客户端向服务器发送消息之前,不会从服务器收到消息。我知道send()会阻止它,但如何解决。如何进行非阻塞聊天,客户端将消息发送到服务器,而其他客户端从服务器获取消息?预先感谢。