0
ソケットを使用してチャットサーバー用のサーバーとクライアントを構築しようとしています。私はselect()を使って複数のソケットから入力を得ることになっていることを知っていますが、それをどうやって行うのかよくわからず、正しく読み込みます。私のコードが座っていると、1つのクライアントから完全に正常に読み込まれますが、2つが開いていると、2番目のクライアントが行うことはすべて無視されます。複数のソケット接続にSelectを使用するC
私は複数のソケットから入力を取ることができるようにselectを正しく実装する方法を知りたいと思います。前もって感謝します。心の中で
#include "../../include/my.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void interrupt();
void interrupt()
{
my_str("Server exiting.\n");
exit(0);
}
int str_to_num(char* str)
{
int i = 0;
int numDigits = 0;
int ret = 0;
while (str[numDigits] != '\0')
{
numDigits++;
}
while (i < numDigits)
{
int digit = str[i];
if (digit < 48 && digit > 57)
return -1;
digit -= 48;
ret += digit * my_pow(10, numDigits - i - 1);
i++;
}
return ret;
}
char* add_null_term(char* str)
{
int i = 0;
while (str[i] != '\0')
i++;
str[i] = '\0';
return str;
}
int main(int argc, char **argv)
{
int sockfd, newsockfd, portnum;
int len;
char buffer[256];
/*char *username = (char*)malloc(256*sizeof(char));*/
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
/*check args*/
if (argc < 2)
{
my_str("Usage: ./server <port_number>\n");
exit(0);
}
portnum = str_to_num(argv[1]);
if (portnum < 1024)
{
perror("Ports below 1024 are reserved for root access.\n");
exit(0);
}
if (portnum < 1 || portnum > 65535)
{
my_str("Port must be between 1 and 65535\n");
exit(0);
}
signal(SIGINT, interrupt);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero((char*)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(portnum);
serv_addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))<0)
{
perror("bind");
exit(0);
}
listen(sockfd, 5);
clilen = sizeof(cli_addr);
while(1)
{
if ((newsockfd=accept(sockfd, (struct sockaddr*)&cli_addr, &clilen)) < 0)
{
perror("accept");
exit(0);
}
usleep(2000);
my_str("Server received: ");
while ((len = read(newsockfd, &buffer, 256)) > 0)
{
buffer[my_strlen(buffer)] = '\0';
if (my_strcmp(buffer, "/") == 0)
{
my_str("Error: command ");
my_str(buffer);
my_str("not found.\n");
bzero((char*)&buffer, sizeof(buffer));
}
/*if (count == 0)
{
my_strcpy(username, buffer);
my_str("setting nickname to: ");
my_str(username);
bzero((char*)&buffer, sizeof(buffer));
my_str(buffer);
count++;
my_str("\n");
}*/
/*else if (my_strncmp(buffer, "/me", 3) == 0)
{
my_str(username);
my_str(" ");
my_str(&buffer[4]);
bzero((char*)&buffer, sizeof(buffer));
my_str("\n");
}
else if (my_strncmp(buffer, "/nick", 5) == 0)
{
my_str("Changing nickname of ");
my_str(username);
my_strcpy(username, &buffer[6]);
my_str(" to ");
my_str(username);
bzero((char*)&buffer, sizeof(buffer));
my_str("\n");
}*/
/*else
{*/
/*my_str(username);
my_str(": ");*/
my_str(buffer);
bzero((char*)&buffer, sizeof(buffer));
my_str(buffer);
my_str("\n");
/*}*/
}
my_str("\nServer: Message end. Waiting for next connection.\n");
}
return 0;
}
私はselectを使用してみました代わりの文の場合、最初に受け入れ、そしてもちろんFD_SETと必要な他を追加しましたビット。サーバーは起動しましたが、入力を受け付けません – spicelord
受け入れの代わりに選択を使用しようとしましたか?選択して受け入れることは、さまざまなことをする。これは、ヘッドホンの代わりにハンマーを使い、まだ音楽を聞くことを期待するようなものです。実際には意味をなさないのです。 – immibis
これは非常に役に立ちます。もちろん彼らはそうします。私は、受け入れの代わりに選択を適切に使うために何をすべきかを知ろうとしています。 – spicelord