PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : c sockets - server



alex
25-01-2003, 17:30
Hallo!

Ja ich weiß, mein erstes Post und gleich eine Frage... Aber es ist dringend und ich zerbrech mir schon Tage den Kopf darüber.
Also folgendes, ich will in ANSI C einen Server schreiben. Einen 'Datenserver' für Datenübertragung im Netzwerk. (Sowas wie FTP, jedoch nicht RFC Konform)
Wenn er fertig ist soll er einen list befehl können (welchen er schon kann), und Daten rauf- und runtergeladen bekommen. Nur hab ich da ein Problem.
Folgendes Szenario:

Ich starte den Server, verbinde mich mit Telnet. Arbeite da kurz rum, schließe den Telnet Client. Alles wunderbar. Wenn ich jedoch ein weiteres mal auf dem Server arbeiten will verweigert er es. Ich kann mich verbinden und so, alles fein, nur wird nichts abgearbeitet. Das liegt sicher an meiner work() Funktion (siehe Code weiter unten).

Und hier den Code:
(Anmk. Falls der Code zu lang sein sollte bitte ich um Benachrichtigung, ich editier dann den Beitrag und lade den Code als tar.gz hoch)



#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>
#include <dirent.h>
#include <string.h>

#define BUFFER_SIZE 1024
#define WD "/home/alex/dataserv/shared"

int work(int client)
{
char recv_buffer[BUFFER_SIZE];
char send_buffer[BUFFER_SIZE];

int data;
DIR* wd;
struct dirent* dp;

strcpy(send_buffer,"Welcome to Dataserver 0.1\nCommands are 'list', 'put <file> [<remote file>]' and 'get <file>'\n");
data = send(client,send_buffer,strlen(send_buffer),0);

while(1)
{
data = recv(client,recv_buffer,sizeof(recv_buffer),0);
if(!data)
{
perror("recv() failed");
return -1;
}
recv_buffer[data-2] = '\0';


if(strcmp(recv_buffer,"list")==0)
{
wd = opendir(WD);
if(wd == NULL)
{
perror("opendir() fehlgeschlagen");
return -1;
}

while((dp=readdir(wd)))
{
strcpy(send_buffer,dp->d_name);
strcat(send_buffer,"\n");
data = send(client,send_buffer,strlen(send_buffer),0);
if(data == -1)
{
perror("send() fehlgeschlagen");
return -1;
}
}
closedir(wd);
recv_buffer[0] = '\0';
}


if(strcmp(recv_buffer,"get")==0)
{
printf("get\n");
}

else if(strcmp(recv_buffer,"put")==0)
{
printf("put\n");
}
}
return 0;
}

int main(int argc, char* argv[])
{
int sock;
int client_size;
int current;

struct sockaddr_in server;
struct sockaddr_in client;

if(argc != 2)
{
fprintf(stderr,"usage: %s <port>\n",argv[0]);
return 1;
}

sock = socket(AF_INET,SOCK_STREAM,0);
if(!sock)
{
perror("socket() fehlgeschlagen");
return 1;
}

server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons((unsigned short int)atol(argv[1]));
server.sin_family = AF_INET;

if (bind(sock,(struct sockaddr*)&server,sizeof(server))==-1)
{
perror("bind() fehlgeschlagen");
return -1;
}

if(listen(sock,3) == -1)
{
perror("listen() fehlgeschlagen");
return -1;
}

while(1)
{
client_size = sizeof(client);
current = accept(sock,(struct sockaddr*)&client,&client_size);
if(!current)
{
perror("accept() fehlgeschlagen");
return -1;
}

printf("Verbindung von %s", inet_ntoa(client.sin_addr));
printf("\n");

work(current);

close(current);
}
return 0;
}

pik7
25-01-2003, 18:44
hallo,

liegt wohl daran das du aus dem work nicht mehr
zum accept zurückkommst wegen dem while(1).
Hab mir mal erlaubt das zu ändern und ein quit
in dein program eingebaut.

EDIT by anda_skoa: ich war so frei den Code in code Tags zu packen, damit man ihn leichter lesen kann.



#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>
#include <dirent.h>
#include <string.h>

#define BUFFER_SIZE 1024
#define WD "/home/alex/dataserv/shared"

int status=0;

int work(int client)
{
char recv_buffer[BUFFER_SIZE];
char send_buffer[BUFFER_SIZE];

int data;
DIR* wd;
struct dirent* dp;

strcpy(send_buffer,"Welcome to Dataserver 0.1\nCommands are 'list', 'put <file> [<remote file>]','get <file>','quit'\n");
data = send(client,send_buffer,strlen(send_buffer),0);

while(status)
{
data = recv(client,recv_buffer,sizeof(recv_buffer),0);
if(!data)
{
perror("recv() failed");
return -1;
}
recv_buffer[data-2] = '\0';


if(strcmp(recv_buffer,"list")==0)
{
wd = opendir(WD);
if(wd == NULL)
{
perror("opendir() fehlgeschlagen");
return -1;
}

while((dp=readdir(wd)))
{
strcpy(send_buffer,dp->d_name);
strcat(send_buffer,"\n");
data = send(client,send_buffer,strlen(send_buffer),0);
if(data == -1)
{
perror("send() fehlgeschlagen");
return -1;
}
}
closedir(wd);
recv_buffer[0] = '\0';
}


if(strcmp(recv_buffer,"get")==0)
{
printf("get\n");
}

else if(strcmp(recv_buffer,"put")==0)
{
printf("put\n");
}

else if(strcmp(recv_buffer,"quit")==0)
{
status=0;
}

}
return 0;
}

int main(int argc, char* argv[])
{
int sock;
int client_size;
int current;

struct sockaddr_in server;
struct sockaddr_in client;

if(argc != 2)
{
fprintf(stderr,"usage: %s <port>\n",argv[0]);
return 1;
}

sock = socket(AF_INET,SOCK_STREAM,0);
if(!sock)
{
perror("socket() fehlgeschlagen");
return 1;
}

server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons((unsigned short int)atol(argv[1]));
server.sin_family = AF_INET;

if (bind(sock,(struct sockaddr*)&server,sizeof(server))==-1)
{
perror("bind() fehlgeschlagen");
return -1;
}

if(listen(sock,3) == -1)
{
perror("listen() fehlgeschlagen");
return -1;
}

while(1)
{
client_size = sizeof(client);
current = accept(sock,(struct sockaddr*)&client,&client_size);
if(!current)
{
perror("accept() fehlgeschlagen");
return -1;
}

printf("Verbindung von %s", inet_ntoa(client.sin_addr));
printf("\n");

status=1;

work(current);

close(current);
}
return 0;
}


gruß

alex
25-01-2003, 19:49
Oh mann ich Vollidiot. Darauf hätte ich auch kommen können. Ich danke dir.