Ich habe eine Aufgabe, ein Serverprogramm zu schreiben, das mehrere Clients akzeptiert. Ich schreibe in C Sprache und versuche dies mit einer select() Anweisung zu erreichen. Ich bin in der Lage zu kompilieren, aber wenn ich Telnet in, bekomme ich eine "Socket-Operation auf Nicht-Socket-Fehler." Ich habe versucht, den Fehler zu erforschen, kann aber nichts zu hilfreich finden. Jede Hilfe wäre willkommen.C lang, Multi-Client Server, Fehler: Socket-Operation auf Nicht-Socket
Der Ausgang meines Servers ist:
$ ./assign2 33333
Waiting for connection...
fd is 0
EchoServ recv error: Socket operation on non-socket
fd is 1
EchoServ recv error: Socket operation on non-socket
EchoServ recv error: Socket operation on non-socket
Der Ausgang des Telnet ist:
$ telnet localhost 33333
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
Welcome to EchoServ chat.
Mein Server-Code:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define PORT 50000
main(int argc, char *argv[])
{
char buf[ BUFSIZ ], /* buffer for incoming data */
*endptr, /* for strtol() */
*message = "Welcome to EchoServ chat. \r\n"; /* welcome message */
int masterSocket, /* main listening socket for server */
newSocket, /* new sockets for connecting clients */
opt = 1, /* for port reuse code */
nBytes, /* # of incoming bytes */
addrlen;
int i,j; /* temp vars */
short int port; /* port number */
fd_set master; /* master file descriptor list */
fd_set temp_fds; /* temp file descriptor list for select() */
int fdmax; /* maximum file descriptor number */
struct sockaddr_in sin;
/* Get port number from the command line, or
set to default port if no arguments were supplied */
if (argc == 2) {
port = strtol(argv[1], &endptr, 0);
if (*endptr) {
fprintf(stderr, "EchoServ: Invalid port number.\n");
exit(EXIT_FAILURE);
}
}
else {
port = PORT;
}
FD_ZERO(&master); /* clear the master and temp sets */
FD_ZERO(&temp_fds);
/* Get an internet domain socket */
if ((masterSocket = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("EchoServ socket error");
exit(1);
}
/* Complete the socket structure */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons(port);
/* Bind the socket to the port number */
if (bind(masterSocket, (struct sockaddr *) &sin, sizeof(sin)) == -1) {
perror("EchoServ bind failed");
exit(1);
}
/* Allow port reuse */
if (setsockopt(masterSocket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
perror("EchoServ setsockopt error");
exit(1);
}
/* Listen for clients that want to connect. */
if (listen(masterSocket, 5) == -1) {
perror("EchoServ listen error");
exit(1);
}
/* add masterSocket to the master set */
FD_SET(masterSocket, &master);
/* track largest file descriptor, starting with masterSocket */
fdmax = masterSocket;
/* Wait for a client connection, then accept it. */
puts ("Waiting for connection...");
while(1){
temp_fds = master; /* copy master set to temp set */
//addrlen = sizeof(sin);
/* wait for activity on a socket */
if (select(fdmax+1, &temp_fds, NULL, NULL, NULL) == -1) {
perror("EchoServ select error");
exit(1);
}
for (i = 0; i <= fdmax; i++){
printf("fd is %d\n", i); /*debug*/
if (FD_ISSET(i, &temp_fds)){ /* true if file descriptor is in set */
/* accept new connection */
if (i == masterSocket){
addrlen = sizeof(sin);
if ((newSocket = accept(masterSocket, (struct sockaddr *) &sin, &addrlen)) == -1)
perror("EchoServ: accept error");
else {
printf("New connection accepted\n"); /*debug*/
FD_SET(newSocket, &master); /* add new connection to master set */
if (newSocket > fdmax) /* update max descriptor */
fdmax = newSocket;
//print details of new connection
printf("New connection on %s:%d, socket fd is %d \n",
inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), newSocket);
//send new connection greeting message
if(send(newSocket, message, strlen(message), 0) == -1)
{
perror("EchoServ welcome message error");
}
puts("Welcome message sent successfully");
}
}
}
/* handle incoming data */
else{
if ((nBytes = recv(i, buf, sizeof(buf), 0)) <= 0){ /* error or closed connection */
if (nBytes == 0) /* connection closed */
printf("EchoServ: socket %d closed by client\n", i);
else /* recv error */
perror("EchoServ recv error");
close(i); /* close socket */
FD_CLR(i, &master); /* remove from master set */
}
else { /* got some data */
for(j = 0; j <= fdmax; j++){
if (FD_ISSET(j, &master)){ /* send data to all sockets */
if(j != i && j != masterSocket){ /* except self and masterSocket */
if (send(j, buf, nBytes, 0) == -1)
perror("EchoServ send error");
}
}
}
}
}
}
}
return(0);
}
Danke für die Hilfe.
Ich bin gespannt: Woher hast du diesen Code-Stil? – cnicutar