PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : socket-Programmierung, send()



MadB
20-10-2003, 22:48
Moinsen Leute,

ich habe mich mal etwas an die Socket-Programmierung gewagt. Schaut bis jetzt ganz gut aus.

Nun habe ich mein Client-Programm insofern aufgebohrt, dass es in einer Endlosschleife läuft, auf Benutzereingaben wartet und je nach Eingabe etwas an den Server sendet.
Leider wird die gewünschte Nachricht nur einmal an den Server übermittelt. Wieso?

Die komplette Initialisierung klappt, Daten werden auch gesendet. Jedoch nur einmal.
Hier mal etwas Code:


...
printf("Client: Verbindung aufgebaut \n");

while(!quit)
{
printMenu();
scanf("%i", &wahl);

switch(wahl)
{
case 1: msg = "1\n\n";
break;
case 2: msg = "2\n\n";
break;
case 9: msg = "Client beendet sich nun\n\n";
quit = 1;
break;
}

/* Verbindung OK, sende Daten */
if(send(sock, msg, strlen(msg), 0) == -1)
{
perror("Client: Daten konnten nicht gesendet werden!");
exit(5);
}

printf("Client: Daten gesendet\n");
}


Was mache ich falsch?
Muss das Socket jedes mal neu aufgebaut werden? Würde ja insofern Sinn machen, da es sich um AF_INET, also TCP, handelt. Ich bin mir jedoch nicht ganz sicher.

Fragende Grüße

Torsten

MadB
22-10-2003, 08:57
Moinsen Leute,

hat sich erledigt.

In der while-Schleife baue ich jedes Mal die Verbindung neu auf. Anscheinend ist das die einzige Lösung

Grüße

Torsten

anda_skoa
22-10-2003, 09:34
Original geschrieben von MadB
In der while-Schleife baue ich jedes Mal die Verbindung neu auf. Anscheinend ist das die einzige Lösung


Das hängt einfach davon ab, was die andere Seite macht.
Wenn die nach dem Empfang die Verbindung schliesst, muss man sie für die nächste Übertragung neu öffnen.

Ciao,
_

MadB
22-10-2003, 20:33
Moinsen,

hmm, eigentlich baue ich die Verbindung nicht ab.
Momentan sehe ich nicht mehr durch.

Eventuell kann mir jemand helfen, wenn ich mal meinen Code bereit stelle:

Der Server:


#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netdb.h>
#include "misc.h"


int main(void)
{
struct sockaddr_in server_addr, client_addr;
int sockfd, new_fd;
int len;
int childstatus;
int quit = 0;
struct message msg;

/* Erzeuge socket */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Server: Konnte socket nicht oeffnen");
exit(1);
}

server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(PORT);
bzero(&(server_addr.sin_zero), 8);

/* Erzeuge die Bindung an die Serveradresse
* (d.h. an einen bestimmten Port) */
if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) == -1)
{
perror("Server: Konnte socket nicht binden");
exit(2);
}

/* Teile dem Socket mit, dass Verbindungswünsche
* von x Clients entgegengenommen werden */
if (listen(sockfd, 5) == -1)
{
perror("Server: listen-Error");
exit(3);
}

printf("Server: gestartet - warte auf Verbindungen\n");

while(1)
{
len = sizeof(struct sockaddr_in);
if ((new_fd = accept(sockfd, (struct sockaddr*)&client_addr, &len)) == -1)
{
perror("Server: accept failed");
// exit(4);
continue;
}

printf("Server: Verbindung angenommen \n");

if(!fork())
{
if (recv(new_fd, &msg, sizeof(msg), 0) == -1)
perror("Server: Fehler bei Datenuebertragung");


printf("Server: erhielt Daten: %i \n", msg.val);

}/* Ende Kind */

}/* Ende while */

close(new_fd);
close(sockfd);

return 0;
}


Nun der Client:


#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "misc.h"

void printMenu(void);

int main(int argc, char *argv[])
{
struct sockaddr_in server_addr;
struct hostent *host_info;
int sockfd;
int wahl, quit = 0;
struct message msg;

if ((host_info = gethostbyname(SERVERIP)) == NULL)
{
printf("Client: Host ist nicht erreichbar\n");
exit(1);
}

server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = inet_addr(SERVERIP);
// server_addr.sin_addr = *((struct in_addr*)host_info->h_addr);
bzero(&(server_addr.sin_zero), 8);

/* open socket */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Client: konnte socket nicht oeffnen\n");
exit(2);
}

if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
{
printf("Client: can't connect to server\n");
exit(3);
}

printf("Client: Verbindung aufgebaut \n");

msg.val = 0;

while(!quit)
{
printMenu();
scanf("%i", &wahl);

switch(wahl)
{
case 1: msg.val = 1;
break;
case 2: msg.val = 2;
break;
case 9: msg.val = 9999;
quit = 1;
break;
default:printf("Falsche Eingabe\n");
break;
}/* end switch */

/* Verbindung OK, sende Daten */
if (send(sockfd, &msg, sizeof(msg), 0) == -1)
{
perror("Client: Daten konnten nicht gesendet werden!");
exit(5);
}
}/* end while */

/* Schließe Verbindung und Socket */
close(sockfd);
return 0;
}


void printMenu(void)
{
printf("\n");
printf("\n 1:\t Zeit holen");
printf("\n 2:\t Linux-Version holen");
printf("\n");
printf("\n 9:\t Client beenden");
printf("\n\nWahl: ");
}


Falls jemand über das struct stolpert:


struct message
{
int val;
};


Fragende Grüße

Torsten

anda_skoa
22-10-2003, 20:58
Ich bin bei C nicht so gut, aber solltest du beim !fork nicht in diesem Bereich drinnen bleiben und beim Fehler exit machen?

Sonst geht doch auch der Kindprozess in die Hauptschleife und blockiert im accept?

Ciao,
_

MadB
22-10-2003, 21:33
Ähm, ich glaube, dass genau da der Hund begraben liegt.
Ich teste nun schon hin und her, bekomme es dennoch nicht hin. Grummel

Grüße

Torsten

MadB
22-10-2003, 21:50
So, habe es nun ganz pervers als Deamon geschrieben.
Mal schauen, wie lange das gut geht. ;)

Grüße

Torsten