Frage zu UDP (datagram socket)



  • thx.
    Hab den link ausprobiert...ich wusste gar nicht , dass man connect() auch auf datagramsockets benutzen kann...ich dachte , dass könnte man nur bei stream sockets benutzen.

    Zu bind():
    Wenn man es weglässt , dann kann die serverseite ja keine Daten mehr empfangen. Habs mal ohne bind() ausprobiert. Des ging net.

    (Ich hoffe , dass ich dich richtig verstanden hab)

    Ich schreibe gerade an nem kleinem Prog. Die Funktionsweise meines prog hat Ähnlichkeiten mit dem tool "netcat".

    (Also mein prog soll über stream sockets verbindungen aufbauen können oder auf diese lauschen und dann halt daten übertragen....das funktioniert auch perfekt...aber bei datagramsockets scheitere ich...da kann ich bis jetzt nur daten von client an server schicken und nicht umgekehrt)

    Netcat ist doch opensource , oder? Weiß jemand wo ich die Quellen zu netcat herkriege? Bei netcat funktioniert der im udp "modus" gut.



  • Könnte jemand mir ein kurzes codebsp geben?



  • #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    
    #define MYPORT 4950    /* the port users will be connecting to */
    
    #define MAXBUFLEN 100
    
    main()
    {
        int sockfd;
        struct sockaddr_in my_addr;    /* my address information */
        struct sockaddr_in their_addr; /* connector's address information */
        int addr_len, numbytes;
        char buf[MAXBUFLEN];
    
        if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
            perror("socket");
            exit(1);
        }
    
        my_addr.sin_family = AF_INET;         /* host byte order */
        my_addr.sin_port = htons(MYPORT);     /* short, network byte order */
        my_addr.sin_addr.s_addr = INADDR_ANY; /* automatically fill with my IP */
        bzero(&(my_addr.sin_zero), 8);        /* zero the rest of the struct */
    
        if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
            perror("bind");
            exit(1);
        }
    
        addr_len = sizeof(struct sockaddr);
        if ((numbytes=recvfrom(sockfd,buf,MAXBUFLEN,0,(struct sockaddr *)&their_addr,
                               &addr_len)) == -1) {
            perror("recvfrom");
            exit(1);
        }
    
        printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
        printf("packet is %d bytes long\n",numbytes);
        buf[numbytes] = '\0';
        printf("packet contains \"%s\"\n",buf);
    
        close(sockfd);
    }
    

    und/oder

    #include <stdio.h> 
        #include <stdlib.h> 
        #include <errno.h> 
        #include <string.h> 
        #include <sys/types.h> 
        #include <netinet/in.h> 
        #include <netdb.h> 
        #include <sys/socket.h> 
        #include <sys/wait.h> 
    
        #define MYPORT 4950    /* the port users will be sending to */
    
        int main(int argc, char *argv[])
        {
            int sockfd;
            struct sockaddr_in their_addr; /* connector's address information */
            struct hostent *he;
            int numbytes;
    
            if (argc != 3) {
                fprintf(stderr,"usage: talker hostname message\n");
                exit(1);
            }
    
            if ((he=gethostbyname(argv[1])) == NULL) {  /* get the host info */
                herror("gethostbyname");
                exit(1);
            }
    
            if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
                perror("socket");
                exit(1);
            }
    
            their_addr.sin_family = AF_INET;      /* host byte order */
            their_addr.sin_port = htons(MYPORT);  /* short, network byte order */
            their_addr.sin_addr = *((struct in_addr *)he->h_addr);
            bzero(&(their_addr.sin_zero), 8);     /* zero the rest of the struct */
    
            if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0, \
                 (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
                perror("sendto");
                exit(1);
            }
    
            printf("sent %d bytes to %s\n",numbytes,inet_ntoa(their_addr.sin_addr));
    
            close(sockfd);
    
            return 0;
        }
    

    Und zwar habe ich das von der Seite
    http://www.ecst.csuchico.edu/~beej/guide/net_old/
    geklaut.

    hf,

    gruss quarky



  • thx...aber das war nicht das Problem.
    Eine Anwendung zu schreiben , die Daten (über datagram sockets) sendet ODER empfängt kann ich schon schreiben.Da hab ich keine Probleme. Das Problem ist folgendes:
    Die Anwendung soll Daten senden _UND_ empfangen.

    Hier der code:
    (bis jetzt kann dieses prog im server un client nur über stream sockets daten senden und empfangen...bei datagram sockets kann mein prog nur daten vom clienten an den server senden)

    #include <stdio.h>
    
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/stat.h>
    
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    
    typedef unsigned long	xtdword;
    typedef unsigned short	xtword;
    typedef unsigned char	xtbyte;
    typedef signed long	xtsdword;
    typedef signed short	xtsword;
    typedef signed char	xtsbyte;
    typedef void*		xtptr;
    
    void	printusage(char* name);
    void	cleanup(void);
    
    int	sock , newsock , input , output;
    
    int	main(int argc , char* argv[])
    {
    	if (argc < 6)
    	{
    		printusage(argv[0]);
    		exit(-1);
    	}
    	input	= 0;
    	output	= 1;
    
    	xtword	port;
    	struct	sockaddr_in	addr;
    	addr.sin_family		= AF_INET;
    
    	xtbyte	buf;
    
    	xtbyte		mode	= 0x00;
    	xtbyte		proto	= 't';	// default: tcp
    
    	atexit(cleanup);
    
    	xtdword		i;
    	for (i = 1; i < argc; i++)
    	{
    		if (strcmp(argv[i] , "-c") == 0)
    		mode		= 'c';
    
    		else if (strcmp(argv[i] , "-s") == 0)
    		mode		= 's';
    
    		if (strcmp(argv[i] , "-u") == 0)
    		proto		= 'u';
    
    		if (strcmp(argv[i] , "-a") == 0)
    		{
    			if (argv[i+1] == 0)
    			{
    				printf("error : IP address not specified\n");
    				exit(-1);
    			}
    
    			if (inet_aton(argv[i+1] , &addr.sin_addr) == 0)
    			{
    				printf("error : invalid IP address\n");
    				exit(-1);
    			}
    		}
    
    		else if (strcmp(argv[i] , "-h") == 0)
    		{
    			if (argv[i+1] == 0)
    			{
    				printf("error : host name not specified\n");
    				exit(-1);
    			}
    
    			struct	hostent*	hostinfo;
    			hostinfo		= (struct hostent*)gethostbyname(argv[i+1]);
    
    			if (hostinfo == 0)
    			{
    				printf("error : unknown host \"%s\"\n" , argv[i+1]);
    				exit(-1);
    			}
    
    			addr.sin_addr		= *(struct in_addr*)hostinfo->h_addr;
    		}
    
    		if (strcmp(argv[i] , "-p") == 0)
    		{
    			if (argv[i+1] == 0)
    			{
    				printf("error : PORT not specified\n");
    				exit(-1);
    			}
    
    			if (argv[i+1][0] == '0' && argv[i+1][1] == 'x')
    			{
    				sscanf(argv[i+1] , "0x%x" , &port);
    				addr.sin_port	= htons(port);
    				addr.sin_port	= htons(port);
    			}
    
    			else
    			{
    				sscanf(argv[i+1] , "%u" , &port);
    				addr.sin_port	= htons(port);
    			}
    		}
    
    		if (strcmp(argv[i] , "-i") == 0)
    		{
    			if (argv[i+1] == 0)
    			{
    				printf("error : INPUT not specified\n");
    				exit(-1);
    			}
    
    			if ((strcmp(argv[i+1] , "stdin") == 0) || (strcmp(argv[i+1] , "STDIN") == 0))
    			input		= 0;
    
    			else
    			{
    				input	= open(argv[i+1] , O_RDONLY);
    				if (input < 0)
    				{
    					printf("error : cannot open \"%s\"\n" , argv[i+1]);
    					exit(-1);
    				}
    			}
    		}
    
    		else if (strcmp(argv[i] , "-o") == 0)
    		{
    			if (argv[i+1] == 0)
    			{
    				printf("error : OUTPUT not specified\n");
    				exit(-1);
    			}
    
    			if ((strcmp(argv[i+1] , "stdout") == 0) || (strcmp(argv[i+1] , "STDOUT") == 0))
    			output		= 1;
    
    			else if ((strcmp(argv[i+1] , "stderr") == 0) || (strcmp(argv[i+1] , "STDERR") == 0))
    			output		= 2;
    
    			else
    			{
    				input	= open(argv[i+1] , O_CREAT | O_WRONLY , ACCESSPERMS);
    				if (input < 0)
    				{
    					printf("error : cannot open \"%s\"\n" , argv[i+1]);
    					exit(-1);
    				}
    			}
    		}
    
    	}
    
    	if (proto == 'u')
    	{
    		sock			= socket(PF_INET , SOCK_DGRAM , IPPROTO_UDP);
    
    		if (sock < 0)
    		{
    			printf("error : cannot create socket (udp)\n");
    			exit(-1);
    		}
    
    		if (mode == 'c')
    		{
    			while (1)
    			{
    				if (read(input , &buf , 1) <= 0)
    				exit(0);
    
    				sendto(sock , &buf , 1 , 0 , (struct sockaddr*)&addr , sizeof(addr));
    			}
    		}
    
    		else if (mode == 's')
    		{
    			addr.sin_addr.s_addr	= htonl(INADDR_ANY);
    			if (bind(sock , (struct sockaddr*)&addr , sizeof(addr)) < 0)
    			{
    				printf("error : cannot bind address to socket\n");
    				exit(-1);
    			}
    
    			socklen_t	len;
    			while (1)
    			{
    				if (recvfrom(sock , &buf , 1 , 0 , (struct sockaddr*)&addr , &len) <= 0)
    				exit(0);
    
    				write(output , &buf , 1);
    			}
    		}
    	}
    
    	else if (proto == 't')
    	{
    		sock		= socket(PF_INET , SOCK_STREAM , IPPROTO_TCP);
    		if (sock < 0)
    		{
    			printf("error : cannot create socket (tcp)\n");
    			exit(-1);
    		}
    
    		if (mode == 'c')
    		{
    			if (connect(sock , (struct sockaddr*)&addr , sizeof(addr)) < 0)
    			{
    				printf("error : cannot connect\n");
    				exit(-1);
    			}
    
    			int pid		= fork();
    
    			if (pid < 0)
    			{
    				printf("error : cannot create process (fork)\n");
    				exit(-1);
    			}
    
    			if (pid == 0)	// child process
    			{
    				while (1)
    				{
    					if (read(input , &buf , 1) <= 0)
    					exit(0);
    
    					write(sock , &buf , 1);
    				}
    			}
    
    			// parent process
    			while (1)
    			{
    				if (read(sock , &buf , 1) <= 0)
    				exit(0);
    
    				write(output , &buf , 1);
    			}
    		}
    
    		else if (mode == 's')
    		{
    			addr.sin_addr.s_addr	= htonl(INADDR_ANY);
    			if (bind(sock , (struct sockaddr*)&addr , sizeof(addr)) < 0)
    			{
    					printf("error : cannot bind address to socket\n");
    				exit(-1);
    			}
    
    			if (listen(sock , 1) < 0)
    			{
    				printf("error : error while listening at port %u (hex: 0x%04x)\n" , port , port);
    				exit(-1);
    			}
    
    			struct	sockaddr_in	clientaddr;
    			size_t	clientaddr_size;
    			newsock		= accept(sock , (struct sockaddr*)&clientaddr , &clientaddr_size);
    			if (newsock < 0)
    			{
    				printf("error : cannot accept connection\n");
    				exit(-1);
    			}
    
    			xtbyte	nbr	= 1;
    			int pid		= fork();
    
    			if (pid < 0)
    			{
    				printf("error : cannot create process (fork)\n");
    				exit(-1);
    			}
    
    			if (pid == 0)	// child process
    			{
    				while (1)
    				{
    					if (read(input , &buf , 1) <= 0)
    					exit(0);
    
    					write(newsock , &buf , 1);
    				}
    			}
    
    			// parent process
    			while (1)
    			{
    				if (read(newsock , &buf , 1) <= 0)
    				exit(0);
    
    				write(output , &buf , 1);
    			}
    		}
    	}
    	return 0;
    }
    
    void	printusage(char* name)
    {
    	printf(
    	"%s [-c/-s] [-p PORTNUM] [-a IP/-h SYMHOSTNAME] [-i SOURCE] [-o DEST] [-u]\n"
    	"-c : client mode\n"
    	"-s : server mode\n"
    	"-p : port\n"
    	"-a : IPv4 address\n"
    	"-h : symbolic host name\n"
    	"-i : input from file/stdin\n"
    	"-o : output to  file/stdout/stderr\n"
    	"-u : If specified , UDP will be used. Otherwise TCP will be used.\n" , name);
    }
    
    void	cleanup(void)
    {
    	close(newsock);
    	close(sock);
    	close(input);
    	close(output);
    }
    


  • Kann mir jemand bei der Lösung dieses Problems helfen?



  • Meinst du jemand guckt sich den ganzen Code an?



  • ich nicht schrieb:

    Meinst du jemand guckt sich den ganzen Code an?

    Man muss au net den ganzen code lesen. Der folgende codeabschnitt reicht.
    Ein paar Personen im Forum (ich weiß nicht mehr wer das war) sagten , dass deren durchschnittlichen programme 1000 oder mehr code zeilen umfassen. Deswegen bin ich davon ausgegangen , dass mein code nicht all zu lang sei.

    if (proto == 'u')
        {
            sock            = socket(PF_INET , SOCK_DGRAM , IPPROTO_UDP);
    
            if (sock < 0)
            {
                printf("error : cannot create socket (udp)\n");
                exit(-1);
            }
    
            if (mode == 'c')
            {
                while (1)
                {
                    if (read(input , &buf , 1) <= 0)
                    exit(0);
    
                    sendto(sock , &buf , 1 , 0 , (struct sockaddr*)&addr , sizeof(addr));
                }
            }
    

    Also nochmal: Kann mir jemand helfen? (Bitte ernste Antwort(en))



  • alex89ru schrieb:

    Ein paar Personen im Forum (ich weiß nicht mehr wer das war) sagten , dass deren durchschnittlichen programme 1000 oder mehr code zeilen umfassen. Deswegen bin ich davon ausgegangen , dass mein code nicht all zu lang sei.

    Klar, 1000 Zeilen sind nicht extrem viel für ein nontriviales Programm.

    Aber selbst 20 Zeilen sind schon zu viel, um sich die mal so auf gut Glück nebenbei durchzulesen, nur weil jemand anders zu faul ist, den gesuchten Fehler näher einzugrenzen.



  • Vielleicht hilft dir das weiter, ist in C geschrieben und funktioniert nur ueber UPD (kannst du ja erweitern). Es ist ein kleiner Chat-Client, den ich vor einigen Wochen fuer die Uni schreiben musste.
    Es gab da zwei Loesungen, eine mit fork und die andere mit filedeskriptoren (meine - find ich im diesem Fall eleganter).

    #include <arpa/inet.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <unistd.h>
    
    int 
    main( argc, argv )
    int argc;
    char **argv;
    {
    	if ( argc < 4 )
    	{
    		fprintf( stderr, "Wrong parameter count!\n\tchat <local port> <remote ip> <remote port>\n" );
    		exit( EXIT_FAILURE );
    	}
    	else
    	{
    		int l_port = atoi( argv[1] );
    		int r_port = atoi( argv[3] );
    		char *r_addr = argv[2];
    
    		if ( l_port < 1024 || r_port < 1024 )
    		{
    			fprintf( stderr, "Wrong port ranges!\n" );
    			exit( EXIT_FAILURE );
    		} 
    		else
    		{
    			int server_socket;
    			int bytes;
    			int max;
    			int sel_result;
    			unsigned int msize;
    			char buffer[BUFSIZ];
    			char buffer_r[BUFSIZ];
    			fd_set filedesc;
    			struct sockaddr_in server_address;
    			struct sockaddr_in client_address;
    			struct sockaddr_in message_address;
    
    			msize = sizeof( message_address );
    
    			/* Verwende hier SOCK_DGRAM stat SOCK_STREAM um eine 
    			 * UDP-Verbindung zu erstellen */
    			if ( ( server_socket = 
    					socket( PF_INET, SOCK_DGRAM, 0) ) == -1 ) 
    			{
    				fprintf( stderr, "%s: socket() failure!\n", argv[0] );
    				exit( EXIT_FAILURE );
    			}
    
    			/* Setzt Daten fuer den Port */
    			server_address.sin_family = PF_INET;
    			server_address.sin_addr.s_addr = INADDR_ANY;
    			server_address.sin_port = htons( l_port );
    
    			if ( bind( server_socket, (struct sockaddr*)&server_address, 
    										sizeof( server_address ) ) == -1 ) 
    			{
    				fprintf( stderr, "%s: bind() failure!\n", argv[0] );
    				close( server_socket );
    				exit( EXIT_FAILURE );
    			}
    
    			/* Hier wird die Nummer des hoechsten file-descriptors ermittelt. 
    			 * STDIN_FILENO hat im Normalfall die Nummer 0, desshalb waere hier 
    			 * die Ermittlung nicht unbedingt zwingend, ist aber aus 
    			 * kompatibilitaetsgrunden zu empfehlen! */
    			max = MAX( server_socket, STDIN_FILENO ); 
    
    			for ( ; ; )
    			{
    				FD_ZERO( &filedesc ); /* leere den filedescriptor */
    				FD_SET( server_socket, &filedesc ); /* server socket hinzufuegen */
    				FD_SET( STDIN_FILENO, &filedesc ); /* STDIN_FILENO hinzufuegen */
    
    				/* select ueber die fd's. Wartet so lange, bis ein ereignis an einen der fd's auftritt.
    				 * Alternativ koennte man eine Zeit-Struktur angeben (letzter Parameter). 
    				 * Wenn der select() Aufruf zurueck kommt enthaelt er alle fd's, an deinen ein Ereignis anliegt,
    				 * da das mehrere sein koennen ist eine doppelte if-Konstruktionn der if-else-Konstruktion 
    				 * vorzuziehen. */
    				sel_result = select( max+1, &filedesc, NULL, NULL, NULL );
    
    				if ( FD_ISSET( server_socket, &filedesc ) ) /* Testet ob am server socket ein Ereignis anliegt */
    				{
    					if ( ( bytes = recvfrom( server_socket, buffer, BUFSIZ, 0, 
    											(struct sockaddr*)&message_address, &msize ) ) == -1 ) /* Empfange Daten */
    					{
    						fprintf( stderr, "%s: recvfrom() failure!\n", argv[0] );
    						close( server_socket );
    						exit( EXIT_FAILURE );
    					}
    					/* if ( buffer[bytes-1] != '\0' ) */
    						buffer[bytes] = '\0'; /* Hier liegt der Fehler begraben, warum? */
    
    					int c_port = htons( message_address.sin_port );
    					char *c_addr =inet_ntoa( message_address.sin_addr );
    
    					/* Ueberpruefe Daten der Gegenstelle und gib eine Fehlermeldung oder die Nachricht aus! */
    					if ( strlen( r_addr ) != strlen( c_addr ) || strncmp( r_addr, c_addr, strlen( r_addr ) ) != 0 )
    					{
    						fprintf( stderr, "IP missmatch: REMOTE IP: %s, CLIENT IP: %s\n", r_addr, c_addr );
    					}
    					else if ( r_port != c_port ) 
    					{
    						fprintf( stderr, "PORT missmatch: REMOTE PORT: %d, CLIENT PORT: %d\n", r_port, c_port );
    					}
    					else 
    					{
    						fflush( stdout );
    						fprintf( stdout, "%s", buffer );
    						fflush( stdout );
    					}
    				}
    				if ( FD_ISSET( STDIN_FILENO, &filedesc ) ) /* Testet ob am standad input ein Ereignis anliegt. */
    				{
    					fflush( stdout );
    					/* if ( fgets( buffer_r, BUFSIZ, STDIN_FILENO ) != NULL ) */
    					if ( ( bytes = read( STDIN_FILENO, buffer_r, BUFSIZ ) ) == -1 ) /* Lese von STDIN */
    					{
    						fprintf( stderr, "%s: read() failure!\n", argv[0] );
    						close( server_socket );
    						exit( EXIT_FAILURE );
    					}
    					buffer_r[bytes] = '\0';
    					fflush( stdin );
    
    					/* Richte die Daten fuer das Senden ein */
    					client_address.sin_family = AF_INET;
    					client_address.sin_addr.s_addr = inet_addr( r_addr );
    					client_address.sin_port = htons( r_port );
    
    					/* Sende die eingegebenen Daten */
    					if( sendto( server_socket, buffer_r, strlen( buffer_r ), 0, 
    								(struct sockaddr *)&client_address, sizeof(client_address) ) == -1)
    					{
    						fprintf( stderr, "%s: sendto() failure!\n", argv[0] );
    						close( server_socket );
    						exit( EXIT_FAILURE );
    					}
    				}
    
    				/* Entferne die fd's, die im fd_set liegen. 
    				 * Ist nicht unbedingt notwendig, weil bei jedem durchgang das
    				 * fd_set geleert wird. */
    				FD_CLR( server_socket, &filedesc );
    				FD_CLR( STDIN_FILENO,  &filedesc );
    			}
    		}
    	}
    	return EXIT_SUCCESS;
    }
    

    Vielleicht kannst du etwas damit anfangen!

    P.S.: Als argumente erhaelt das Programm den lokalen Port, auf den es horchen und senden soll, die IP-Adresse und den Port der Gegenstelle.



  • @moe szyslak:
    Danke erstmal. Ähm , ich hab da ne Frage zu deinem code:
    D hast folgendes geschrieben:

    server_address.sin_addr.s_addr = INADDR_ANY;
    

    Muss das nicht so heißen?

    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    

    Oder ist es egal?

    @nman:
    Ich zu Faul? Sorry , aber ich hab selebr ne Zeit lang alles mögliche ausprobiert und ich komme einfach net weiter.
    zu "fehler eingrenzen": Lies den anfang vom thread durch...



  • Ja, ich glaube schon - hab wahrscheinlich nur ne alte version am rechner.
    Mit htonl funktionierts auf jeden Fall!

    Wenn du die Funktion verwendest bist du auf der sicheren Seite. Im Netzwerk-Verkehr ist es so, dass die Daten nach einem bestimmten Schema versendet werden (LITTLE/BIG ENDIAN). Das heist, verwendest du die Methode nicht kann es sein, dass du z.B. Probleme hast, wenn du von PowerPc auf x 86 sendest oder umgekehrt.



  • moe szyslak schrieb:

    Ja, ich glaube schon - hab wahrscheinlich nur ne alte version am rechner.
    Mit htonl funktionierts auf jeden Fall!

    Wenn du die Funktion verwendest bist du auf der sicheren Seite. Im Netzwerk-Verkehr ist es so, dass die Daten nach einem bestimmten Schema versendet werden (LITTLE/BIG ENDIAN). Das heist, verwendest du die Methode nicht kann es sein, dass du z.B. Probleme hast, wenn du von PowerPc auf x 86 sendest oder umgekehrt.

    Ok. Hab mich nämlich schon gewundert , da ich es MIT htonl() gelernt hab , in letzter Zeit aber öffters mal codebsp gesehen hab , welche kein htonl verwendeten.



  • alex89ru schrieb:

    Ich zu Faul? Sorry , aber ich hab selebr ne Zeit lang alles mögliche ausprobiert und ich komme einfach net weiter.

    Ja, eindeutig zu faul. Sonst hättest Du zB auch die Netcat-Sourcen sofort gefunden.

    zu "fehler eingrenzen": Lies den anfang vom thread durch...

    Hab ich. Du beschreibst Deine Probleme und knallst uns dann 327 Zeilen Code hin. Auf sowas antwortet Dir garantiert niemand, dem nicht gerade extrem langweilig ist.

    http://www.catb.org/~esr/faqs/smart-questions.html



  • nman schrieb:

    alex89ru schrieb:

    Ich zu Faul? Sorry , aber ich hab selebr ne Zeit lang alles mögliche ausprobiert und ich komme einfach net weiter.

    Ja, eindeutig zu faul. Sonst hättest Du zB auch die Netcat-Sourcen sofort gefunden.

    zu "fehler eingrenzen": Lies den anfang vom thread durch...

    Hab ich. Du beschreibst Deine Probleme und knallst uns dann 327 Zeilen Code hin. Auf sowas antwortet Dir garantiert niemand, dem nicht gerade extrem langweilig ist.

    http://www.catb.org/~esr/faqs/smart-questions.html

    Sorry.



  • alex89ru schrieb:

    @moe szyslak:
    Danke erstmal. Ähm , ich hab da ne Frage zu deinem code:
    D hast folgendes geschrieben:

    server_address.sin_addr.s_addr = INADDR_ANY;
    

    Muss das nicht so heißen?

    server_address.sin_addr.s_addr = htonl(INADDR_ANY);
    

    Oder ist es egal?

    INADDR_ANY
    bzw

    in.h schrieb:

    typedef uint32_t in_addr_t;
    #define INADDR_ANY ((in_addr_t) 0x00000000)

    und zu htonl:

    <a href= schrieb:

    <arpa/inet.h>">The htonl() and htons() functions return the argument value converted from host to network byte order.

    bzw

    uint32_t htonl(uint32_t hostlong);
    


  • @moe szyslak:
    thx...jetzt funktioniert mein prog einwandfrei. 👍



  • hallo,

    ich habe in der firma die wundervolle aufgabe bekommen ein windows-programm das zyklisch istwert-daten über udp von einer sps abholt auf linux umzusetzen. und nach 3 tagen googeln ist dass das erste brauchbare beispiel das mich auf anhieb sehr viel weiter gebracht hat. echt klasse! 👍 👍 👍

    nun hätte ich aber da ein paar fragen:

    bei select() kann ich ja 3 fd-sets übergeben, nur wenn ich eins für lesen und eins für schreiben übergebe greift mein timeout nicht mehr:

    .
    .
    .
    
    FD_ZERO(&writefd);
    FD_SET(sock, &writefd);
    FD_SET(STDIN_FILENO, &writefd);
    FD_ZERO(&readfd);
    FD_SET(sock, &readfd);
    FD_SET(STDIN_FILENO, &readfd);
    
    timeout.tv_sec  = 1;
    timeout.tv_usec = 0;
    
    sel_result = select(max +1, &readfd, &writefd, NULL, &timeout);
    
    if(FD_ISSET(sock, &writefd)) {
        printf("daten senden\n");
    }
    
    if(FD_ISSET(sock, &readfd)) {
        printf("daten empfangen\n");
    }
    
    .
    .
    .
    

    dann habe ich das so umgebaut:

    .
    .
    .
    FD_ZERO(&writefd);
    FD_SET(sock, &writefd);
    FD_SET(STDIN_FILENO, &writefd);
    
    timeout.tv_sec  = 1;
    timeout.tv_usec = 0;
    
    sel_result = select(max +1, NULL, &writefd, NULL, &timeout);
    
    if(FD_ISSET(sock, &writefd)) {
        printf("daten senden\n");
    }
    
    FD_ZERO(&readfd);
    FD_SET(sock, &readfd);
    FD_SET(STDIN_FILENO, &readfd);
    
    timeout.tv_sec  = 1;
    timeout.tv_usec = 0;
    
    sel_result = select(max +1, &readfd, NULL, NULL, &timeout);
    
    if(FD_ISSET(sock, &readfd)) {
        printf("daten empfangen\n");
    }
    .
    .
    .
    

    dann funktioniert auch jedesmal mein timeout, nur: welches ist jetzt die "richtige" lösung? oder macht man das überhaupt so? oder einfach nur stur senden und dann den timeout bzw. die rückmeldung von sendto() verarbeiten um zu sehen ob meine sps überhaupt übers netzwerk erreichbar ist?

    gruss, marco

    p.s. ja, tcp/ip illustrated vom stevens hab ich bestellt, ist leider noch unterwegs *gnarf*

    p.p.s. der code-schnipsel sollte in die faq eingetragen werden 🙂


Anmelden zum Antworten