Server für mehrere Benutzer und IP?
-
Hallo,
Ich will einen Server in C programmieren auf den mehrere Personen verbinden können. Wenn sich aber mehrere Leute kommen man aber in die Warteschleife bis der andere die Verbindung getrennt hat... Wie kann ich das umgehen?
Wie komme ich an die IP des jenigen der auf den Server verbindet?[cpp/* prg2.c
* Beispiel für einen Server für Unix
* (für Win32 geringe Änderungen notwendig)
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>#define BUFFER_SIZE 1024
int handling(int c)
{
char buffer[BUFFER_SIZE], name[BUFFER_SIZE];
int bytes;strcpy(buffer, "My name is: ");
bytes = send(c, buffer, strlen(buffer), 0);
if (bytes == -1)
return -1;bytes = recv(c, name, sizeof(name) - 1, 0);
if (bytes == -1)
return -1;
name[bytes] = '\0';sprintf(buffer, "\nHello %s, nice to meet you!\r\n", name);
bytes = send(c, buffer, strlen(buffer), 0);
if (bytes == -1)
return -1;return 0;
}int main(int argc, char *argv[])
{
int s, c;
socklen_t cli_size;
struct sockaddr_in srv, cli;if (argc != 2)
{
fprintf(stderr, "usage: %s port\n", argv[0]);
return 1;
}s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1)
{
perror("socket() failed");
return 2;
}srv.sin_addr.s_addr = INADDR_ANY;
srv.sin_port = htons( (unsigned short int) atol(argv[1]));
srv.sin_family = AF_INET;
if (bind(s, (struct sockaddr*) &srv, sizeof(srv)) == -1)
{
perror("bind() failed");
return 3;
}if (listen(s, 3) == -1)
{
perror("listen() failed");
return 4;
}for(;;)
{
cli_size = sizeof(cli);
c = accept(s, (struct sockaddr*) &cli, &cli_size);
if (c == -1)
{
perror("accept() failed");
return 5;
}
printf("client from %s", inet_ntoa(cli.sin_addr));
if (handling(c) == -1)
fprintf(stderr, "%s: handling() failed", argv[0]);
/* hier empfiehlt sich kein return mehr, weil sonst der
* ganze Server beendet wird wenn ein Client wegstirbt. Das ist
* natürlich nicht sinnvoll.
*/close(c);
}return 0;
}[/cpp]
-
Hallo,
den ersten Teil verstehe ich:
Ich will einen Server machen auf dem siche rmehrere Personen einlogen können und gleichzeitig etwas machen können.
SSH drauf, Benutzer anlegen und warten, bis sich wer einloggt.
Wenn sich aber mehrere Leute amelden kommt man aber in die Warteschleife bis der andere die Verbindung getrennt hat... Wie kann ich das umgehen?
Hast du ne ISDN-Einwahl? Ansonsten verstehe ich das Problem nicht....
Wie komme ich an die IP des jenigen der auf den Server verbindet?
Netstat z. B.
-
@Carsten, waren die Antworten ernst gemeint oder willst den Plutonium einfach nur verarschen?
@topic:
http://www.c-plusplus.net/forum/viewtopic.php?t=83611
Das ist ein thread wo ich dasselbe Problem hatte.
Einfach mal die Links durchgehen, dann ist das kein problem mehrUnd mal so ne Frage noch:
Wie kann ich structs, die beide Seiten kennen übergeben?
Immer wenn ich beim Clien/Server machesend(socket,(void*)&myStruct,sizeof(myStruct),0);
kommt auf der anderen Seite mit dem Code
recv(socket,(void*)&myStruct,sizeof(myStruct),0);
der Fehler:
Resource temporarily unavailable
-
Hallo,
dein Problem ist, dass im folgenden Code:
for( ; ; ) { cli_size = sizeof(cli); c = accept(s, (struct sockaddr*) &cli, &cli_size); if (c == -1) { perror("accept() failed"); return 5; } printf("client from %s", inet_ntoa(cli.sin_addr)); if (handling(c) == -1) fprintf(stderr, "%s: handling() failed", argv[0]); /* hier empfiehlt sich kein return mehr, weil sonst der * ganze Server beendet wird wenn ein Client wegstirbt. Das ist * natürlich nicht sinnvoll. */ close(c); }
Sobald sich jemand verbindet, geht dein Server solange nicht in den accept-
Status zurueck, bis der eine Client abgearbeitet wurde.In diesem Zusammenhang solltest du dir vielleicht mal die Funktion fork()
anschauen (threads sind hier, imho, ersteinmal ueberdimensioniert).Mit accept in Verbindung mit fork() liefert dir dann folgendes Szenario:
Ein Client verbindet sich, accept liefert einen Socket zurueck, der die
Verbindung zum Client repraesentiert. Nun erstellst du mit fork() ein
Kindprozess, erfolgt dies erfolgreich, dann haendelt der Kindprozess den
Client. Der Parentprozess schliesst den Socket (beim fork() wird eine
kopie vom selbigem erstellt) und kehrt in den accept-Status zurueck:pid_t child; for( ; ; ) { cli_size = sizeof(cli); c = accept(s, (struct sockaddr*) &cli, &cli_size); if (c == -1) { perror("accept() failed"); return 5; } printf("client from %s", inet_ntoa(cli.sin_addr)); switch((child = fork())) { case -1: printf("fork() failed"); close(c); break; case 0: /*kindprozess*/ /*der elternprozess kehr wieder in den accept-Status zurueck*/ if (handling(c) == -1) fprintf(stderr, "%s: handling() failed", argv[0]); break; default: /*elternprozess*/ close(c); break; } }
mfg
v R
-
Hallo,
stealth00 schrieb:
@Carsten, waren die Antworten ernst gemeint oder willst den Plutonium einfach nur verarschen?
Das war schon ernst gemeint, allerdings stand vor der Änderung was völlig anderes da.
-
@Carsten:
Dann Sry, dachte das wäre ne übliche Verarsche@topic:
virtuell Realisticer, ich halte deinen Ansatz für zu kompliziert.
bei http://www.lowtek.com/sockets/select.html findest du Quellcode der genau zu deinem Problem passt.
Bei der Methode umgehst du auch Threads, die meiner Meinung, vor allem wenn du dich noch nicht sehr gut auskennst eher für Fehler sorgen als für Lösungen (war zumindest bei mir so...)