Broadcast port



  • Hallo
    Ich möchte ein Gerät im LAN suchen, wenn das Gerät antwortet möchte ich die IP des Gerätes haben.
    Das senden funktioniert und das Gerät antwortet auch (überprüft mit LANSNIFFER),
    mein Problem ist das das Gerät immer auf einen anderen Port antwortet.
    Wie setzte ich so eine art "PORT_ANY", oder gibt es eine andere möglichkeit.
    Hier mein Code:

    int main(void)
    {
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,0), &wsaData);
    
    SOCKET sockRecv;
    SOCKADDR_IN sinRecv;
    sockRecv = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    
    sinRecv.sin_family = AF_INET; 
    sinRecv.sin_port = htons (1234); //0 funzt net
    sinRecv.sin_addr.s_addr = htonl (INADDR_ANY); //
    bind(sockRecv, (LPSOCKADDR)&sinRecv, sizeof(sinRecv));
    
    SOCKET sock;
    SOCKADDR_IN sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = INADDR_BROADCAST;
    sin.sin_port = htons (4519); 
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    int i = 1;
    setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&i, 1);
    connect(sock, (SOCKADDR *)&sin, sizeof(sin));
    
    const int nSendBufferLen = 4;
    BYTE sendBuffer[4] = { 0x00, 0xf3, 0x00, 0xf3};
    long lBytesSend = send(sock, (const char*) sendBuffer, nSendBufferLen, 0);
    int nBytesRecv;
    char recvBuffer[200];
    memset(recvBuffer, 0, sizeof(recvBuffer)); 
    
    i = 0;
    nBytesRecv = recv(sockRecv, recvBuffer, sizeof(recvBuffer)-1, 0); 
    printf("Receive %d, Bytes %d\n%s\n\n", ++i, nBytesRecv,recvBuffer); 
    while(nBytesRecv)
    {
    nBytesRecv = recv(sockRecv, recvBuffer, sizeof(recvBuffer)-1, 0); 
    printf("Receive %d, Bytes %d\n%s\n\n", ++i, nBytesRecv,recvBuffer); 
    } 
    
    WSACleanup();
    closesocket(sock);
    closesocket(sockRecv);
    
    return 0;
    }
    


  • Also der Port ist natürlich immer der mit dem die Anfrage gesendet wurde,
    und dieser ist immer eine anderer und nicht wie festgelegt: 1234 !
    Kann keiner helfen



  • Also habe Obiges Problem mal zur Seite geschoben, doch da ist schon das Nächste:
    Ich empfange Daten von einem client, das Problem ist das der client die Daten willkürlich aufsplittet (3+17, 11+9,usw...)
    Mit diesem code wird zwar alles empfangen aber ich bleibe in der schleife hängen.

    //...........
            FD_ZERO(&rfds);
    	FD_SET(lansock, &rfds);
    	tv.tv_sec = 2;
    	tv.tv_usec = 0;
     //...............
    		select(lansock, &rfds, NULL, NULL, &tv);
    
    			do 
    			{
    				if (FD_ISSET(lansock,&rfds))
    				{
    				irecv=recv(lansock,buf,20,0);
    				strncat(readbuffer,buf,irecv); //2tes Problem
    				}
    
    			}
    				while (irecv>0);
    //......
    

    Mein 2tes Problem ist dann das zB der erste Datensatz so aussieht:
    (HEX) 41 dd 83 31 00 00 00 32
    und der zweite zB so:
    2f 31 38 ....
    strncat schneidet mir die "32", also alles nach der 00 ab;
    gibts da eine andere funktion (lösung)
    lg m



  • Hi

    Ja ist ja klar das eine Stringfunktion dort an dieser stelle ein cat macht !
    Die Funktion sieht es als Stringterminierungszeichen an und endet dort !
    Du musst das mit memcpy() machen.

    Zu deinem 1. Problem: Da kann dir wirklich keiner helfen ! Das wwird vom jeweiligen Kernel des OS hantiert. Da kannst du sehr wenig oder garnichts machen.
    Warum willst du den das er auf einem gewissen Port ankommt ? ist ja vollig egal !
    Das ist ja der Port den er dir zu verfügung stellt an seinem Sys. damit du auch mit im komunizieren kannst! Verstehe nicht was dein Problem ist ?

    lowbyte



  • Hi

    Und rev() kannst du so nicht verwenden !

    Bei recv() / send() ist man nicht sicher ob auch wirklich alles gesendet wurde, darum muss man dafür sorgen.
    Du kannst nicht einfach nochmal die Daten vom zweiten empfangenen stream in den gleichen ort des Empfangspuffer kopieren.

    Falsch !

    do
                {
                    if (FD_ISSET(lansock,&rfds))
                    {
                    irecv=recv(lansock,buf,20,0);
                    strncat(readbuffer,buf,irecv); //2tes Problem
                    }
    
                }
                    while (irecv>0);
    

    Versuche es anhand dieser routine zu verstehen.
    Wenn du zum Bsp. 20 byte empfangen willst, dir der remotehost aber nur 10 byte schickt, dann musst du dafür sorgen das beim nächsten durchgang der (Rest oder auch nicht) in den empfangspuffer 10 byte weiter kopierst (BUFFER[10] = data;).

    // Funktion Send-controll
    
    long send_data(int socket ,unsigned char *sbuf ,long len )
    
    {
    	long rc_2=0;
    	long rc_3=0;
    	long total=0;
    
    	do
    	{
    		rc_2 = (len - rc_3);												// Ganze Len - rc_3 = rc_2
    																			// rc_3 beim 1.t durchlauf 0
    		rc_3 = send(socket ,&sbuf[rc_3] ,rc_2 ,0);							// Bei der send() funktion muss selber	
    		if(rc_3==SOCKET_ERROR) {											// geprüft werden ob alle Daten des 
    			printf("Send Fehler :%i", WSAGetLastError());					// send buffers gesendet wurden.
    			closesocket(connectedSocket);									// Die anzahl der wirklich gesendeten
    			getchar();														// zeichen kann man aus dem return wert
    			exit(1);														// der send funktion entnehmen.
    		}
    
    		total += rc_3;														// Return von rc_3 an total übergeben
    
    	}
    	while(total!=len);														// Wen total ungleich gesamt len dann
    																			// schleife widerholen und nicht
    																			// gesendete zeichen nach senden
    
    	return total;
    
    }
    
    // Funktion Recv-controll
    
    long recv_data(int socket ,unsigned char *rbuf ,long len)
    
    {
    	long rc_2=0;
    	long rc_3=0;
    	long total=0;
    
    	do
    	{
    
    		rc_2 = (len - rc_3);
    
    		rc_3 = recv(socket ,&rbuf[rc_3] ,rc_2 ,0);
    		if(rc_3==SOCKET_ERROR) {
    			printf("Recv Fehler :%i", WSAGetLastError());
    			closesocket(connectedSocket);
    			getchar();
    			exit(1);
    		}
    
    		total += rc_3;
    
    	}
    	while(total!=len);
    

    lowbyte



  • Hi
    Danke für Deine Anwort, aber leider weiß ich die länge von "recv" (der zu empfangenden Daten) nicht. Wie kann ich die Schleife FD_ISSET(.... beenden ?
    lg Mero



  • Hi

    Kannst die länge zuerst übertragen, dan weist du sie.

    lowbyte


Anmelden zum Antworten