Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » GNU/Linux » recvfrom()

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
20.05.2003, 09:34 Uhr
~arkantos
Gast


Hallo Leute,
hier mein Problem:
Die Funktion recvfrom() blockiert ja normalerweise in der while(1)-Schleife, bis ein Client anfrägt.
Bei mir ist dass eine Endlosschleife, warum?


C++:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main()
{
int server_sockfd, client_sockfd;                        //Variablen definieren
int server_len, client_len;
struct sockaddr_in server_address, client_address;

server_sockfd=socket(AF_INET, SOCK_DGRAM, 0);                //Socket für server einrichten

server_address.sin_family=AF_INET;                        //Art der Domäne setzen
server_address.sin_addr.s_addr=htonl(INADDR_ANY);                //IP-Adresse umwandeln
server_address.sin_port=htons(9734);                        //Festen Port setzen
server_len=sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address, server_len);        //Socket wird mit server zusammmengebunden


listen(server_sockfd, 5);                            //Warteschleife

    while(1)
    {
        char ch;
        printf("server waiting...\n");
        client_len=sizeof(client_address);
        server_len=sizeof(server_address);
        
        recvfrom(client_sockfd, &ch, 1, 0, (struct sockaddr *)&client_address, &client_len);
        ch++;

        sendto(client_sockfd, &ch, 1, 0, (struct sockaddr *)&client_address, client_len);

        close(client_sockfd);
    
    
    }


}





Grüße arkantos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
20.05.2003, 10:16 Uhr
virtual
Sexiest Bit alive
(Operator)


Vermutlich weil das recvfrom immer fehlschlägt: solange du kein accept machst, bekommst Du auch kein Handle, welches normalerweise das Clientsocket initialisieren würde.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
20.05.2003, 10:20 Uhr
~arkantos
Gast


aber ich brauch bei einer UDP-Verbindung kein accept wie bei TCP.

recvfrom() beinhaltet eigentlich auch das accept.

woran kann es dann liegen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
20.05.2003, 10:38 Uhr
virtual
Sexiest Bit alive
(Operator)


Ach, nicht richtig hingeguckt:
Dann ist der listen-Call aber auch Müll. Und das ändert auch nichts da dran, daß client_sockfd nicht initialisiert ist und damit recvfrom einen Fehler zurück liefert.
Der erste parameter von recvfrom muß das von Dir selbst erstellte Socket sein (server_sockfd). Da Du mit UDP connectionsless arbeitest, bekommst Du auch kein CLient socket, wohl aber die Addressdaten vom Client zurück geliefert.
Analoges gilt für den sendto aufruf: Du hast - wie das connectionless bei UDP ja betont - kein Socket vom Client und damit keine Verbindung. Du identifizierst den Client allein über die Addressdaten.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
20.05.2003, 10:48 Uhr
virtual
Sexiest Bit alive
(Operator)


Dieses Programm zeigt die Empfangsrichtung für Windows und Linux, TCP und UDP. Ist zwar nicht genau das was Du willst, weil es recv an Stelle von recvfrom verwendet, aber es zeigt ungefähr wie es läuft (Die Namensauflösun des hostnames ist komplizierter als erforderlich):

C++:
#include    <stdlib.h>
#include    <stdio.h>
#if _WIN32
#   include <windows.h>
#else
#   include <errno.h>
#   include <sys/socket.h>
#endif


#ifdef _WIN32
#define     errno WSAGetLastError
#endif



#define USAGE fprintf(stderr, "usage: %s [-u|--udp] [-t|--tcp] port\n", szProgramName)

int
main(
    int nArgC,
    char** pszArgV)
{
#ifdef _WIN32
    WSADATA oWSA;
#endif
    char szHostname[64];
    const char* szProgramName;
    int nPort;
    int bUseTCP = 0;
    int bUseUDP = 0;
    int nUDPSocket;
    int nTCPSocket;
    struct hostent* poHostEntry;
#ifdef _WIN32
    struct sockaddr_in oSockAddr;
#else
    struct sockaddr oSockAddr;
#endif
    int nLen;
    int nSocket;
    char szBuffer[100];
    static long nonblock = 1;

    /*
     * Get invokation name
     */

    szProgramName = *pszArgV + strlen(*pszArgV);
    while (szProgramName>*pszArgV && szProgramName[-1]!='\\' && szProgramName[-1]!='/' )
    {
        szProgramName--;
    }

    /*
     * Check command line
     */

    pszArgV++; nArgC--;
    while (nArgC)
    {
        if ('-' != pszArgV[0][0])
        {
            break;
        }else if (0==strcmp("--", pszArgV[0]))
        {
            pszArgV++; nArgC--;
            break;
        }else if (0==strcmp("-u", pszArgV[0]) || 0==strcmp("--udp", pszArgV[0]))
        {
            bUseUDP = 1;
            pszArgV++; nArgC--;
        }else if (0==strcmp("-t", pszArgV[0]) || 0==strcmp("--tcp", pszArgV[0]))
        {
            bUseTCP = 1;
             pszArgV++; nArgC--;
        }else
        {
            fprintf(stderr, "%s: unknown option %s\n", szProgramName, pszArgV[0]);
            USAGE;
            exit (EXIT_FAILURE);
        }
    }

    if (1 != nArgC)
    {
        fprintf(stderr, "%s: illegal command line\n", szProgramName);
        USAGE;
        exit (EXIT_FAILURE);
    }

    if (1 != sscanf(pszArgV[0], "%d", &nPort) && nPort<0 || nPort>65535)
    {
        fprintf(stderr, "%s: illegal port number (allowed values: 0...65535)\n", szProgramName);
        exit (EXIT_FAILURE);
    }
    if (!bUseTCP && !bUseUDP)
    {
        bUseUDP = 1;
        bUseTCP = 1;
    }

    /*
     * Initialize Socket library and other variables (without deeper version checking)
     */

#ifdef _WIN32
    if (0 != WSAStartup(MAKEWORD(2,0), &oWSA))
    {
        fprintf(stderr, "%s: WSAStartup() failed: %d\n", szProgramName, errno);
        exit (EXIT_FAILURE);
    }
#endif
    if (-1 == gethostname(szHostname, sizeof(szHostname)))
    {
        fprintf(stderr, "%s: gethostname() failed: %d\n", szProgramName, errno);
        exit (EXIT_FAILURE);
    }
    if (NULL == (poHostEntry = gethostbyname(szHostname)))
    {
        fprintf(stderr, "%s: gethostbyname() failed: %d\n", szProgramName, errno);
        exit (EXIT_FAILURE);
    }

    memset(&oSockAddr, 0, sizeof(oSockAddr));
    oSockAddr.sin_family = poHostEntry->h_addrtype;
    memcpy((char *)&oSockAddr.sin_addr, poHostEntry->h_addr, poHostEntry->h_length);
    oSockAddr.sin_port = htons((short)nPort);

    /*
     * Setup UDP Socket, if requested
     */

    if (bUseUDP)
    {
        /*
         * Create and bind socket to port
         */

        nUDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (INVALID_SOCKET == nUDPSocket)
        {
            fprintf(stderr, "%s: socket() for UDP failed: %d", szProgramName, errno);
            exit(EXIT_FAILURE);
        }
        ioctlsocket(nUDPSocket, FIONBIO, &nonblock);
        if (SOCKET_ERROR == bind(nUDPSocket, (struct sockaddr*)&oSockAddr, sizeof(oSockAddr)))
        {
            fprintf(stderr, "%s: bind() for UDP failed: %d", szProgramName, errno);
            exit(EXIT_FAILURE);
        }

        /*
         * Write some information
         */

        printf("Opened UDP socket %d on %s:%d\n", nUDPSocket, szHostname, nPort);
    }

    /*
     * Setup TCP Socket, if requested
     */

    if (bUseTCP)
    {
        /*
         * Create and bind socket to port
         */

        nTCPSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (INVALID_SOCKET == nTCPSocket)
        {
            fprintf(stderr, "%s: socket() for TCP failed: %d", szProgramName, errno);
            exit(EXIT_FAILURE);
        }
        ioctlsocket(nTCPSocket, FIONBIO, &nonblock);
        if (SOCKET_ERROR == bind(nTCPSocket, (struct sockaddr*)&oSockAddr, sizeof(oSockAddr)))
        {
            fprintf(stderr, "%s: bind() for TCP failed: %d", szProgramName, errno);
            exit(EXIT_FAILURE);
        }

        /*
         * Write some information
         */

        printf("Opened TCP socket %d on %s:%d\n", nTCPSocket, szHostname, nPort);
    }

    /*
     * Loop
     */

    for(;;)
    {
        fd_set oReadSet;
        struct timeval oTimeout = {5, 0};
        /*
         * Wait for timeout or one of the sockets
         */


        FD_ZERO(&oReadSet);
        if (bUseUDP) FD_SET(nUDPSocket, &oReadSet);
        if (bUseTCP) FD_SET(nTCPSocket, &oReadSet);
        printf("Waiting for data on any of the sockets...\n");
        switch (select(0, &oReadSet, NULL, NULL, &oTimeout))
        {
        case 0:
            printf("No bytes received yet...\n");
            break;
        case SOCKET_ERROR:
            fprintf(stderr, "%s: select() failed: %d\n", szProgramName, errno);
            exit (EXIT_FAILURE);
            break;
        default:
            nLen = 0;
            if (bUseUDP && FD_ISSET(&oReadSet, nUDPSocket))
            {
                nSocket = nUDPSocket;
            }else if (bUseTCP && FD_ISSET(&oReadSet, nTCPSocket))
            {
                nSocket = nUDPSocket;
            }else
            {
                fprintf(stderr, "%s: whoops - no socket has data: %d\n", szProgramName, errno);
                exit (EXIT_FAILURE);
                break;
            }
            do            {
                nLen = recv(nSocket, szBuffer, sizeof(szBuffer), 0);
                if (nLen>=0)
                {
                    printf("Received %d bytes from the %s socket\n", nLen, nSocket==nUDPSocket? "UDP":"TCP");
                }else
                {
                    fprintf(stderr, "%s: recv() failed: %d\n", szProgramName, errno);
                    exit (EXIT_FAILURE);
                }
            } while (nLen>0);
            break;
        }
    }

    return EXIT_SUCCESS;
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
20.05.2003, 13:16 Uhr
~arkantos
Gast


Versteh des trotzdem noch net, will einfach mein programm von TCP, was funktionierte auf UDP umschreiben.

Hier der Server:


C++:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main()
{
int server_sockfd, client_sockfd;                        //Variablen definieren
int server_len, client_len;
struct sockaddr_in server_address, client_address;

server_sockfd=socket(AF_INET, SOCK_DGRAM, 0);                //Socket für server einrichten

server_address.sin_family=AF_INET;                        //Art der Domäne setzen
server_address.sin_addr.s_addr=htonl(INADDR_ANY);                //IP-Adresse umwandeln
server_address.sin_port=htons(9734);                        //Festen Port setzen
server_len=sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address, server_len);        //Socket wird mit server zusammmengebunden


listen(server_sockfd, 5);                            //Warteschleife

    while(1)
    {
        char ch;
        printf("server waiting...\n");
        client_len=sizeof(client_address);
        //client_sockfd=accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);    //Verbindung angenommen
        server_len=sizeof(server_address);
        recvfrom(server_sockfd, &ch, 1, 0, (struct sockaddr *)&client_address, &client_len);
        //read(client_sockfd, &ch, 1);                    //von Client zeichen lesen
        ch++;
        //write(client_sockfd, &ch, 1);                    //Zeichen verändern und zurückschreiben

        sendto(server_sockfd, &ch, 1, 0, (struct sockaddr *)&client_address, client_len);

        close(server_sockfd);
    
    
    }


}





Hier der Client:


C++:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main()
{
    int sockfd, server_sockfd;                //Variablendefinitionen
    int len;
    struct sockaddr_in address, server_address;
    int result;
    char ch='A';
    int server_len, client_len;



sockfd=socket(AF_INET, SOCK_DGRAM, 0);            //Socket wird erstellt

address.sin_family=AF_INET;                    //Domäne eingerichtet
address.sin_addr.s_addr=inet_addr("127.0.0.1");            //socket wird auf festen port + IP gesetzt
address.sin_port=htons(9734);
len=sizeof(address);
bind(sockfd, (struct sockaddr *)&address, len);

//result=connect(sockfd, (struct sockaddr *)&address, len);
result=sendto(sockfd, &ch, 1, 0, (struct sockaddr *)&address, sizeof(address));

if(result== -1)
    {
    perror("oops: client3");
    exit(1);
    }

//write(sockfd, &ch, 1);                    //Zeichen zum server geschrieben
//read(sockfd, &ch, 1);                    //Zeichen vom server empfangen
server_len=sizeof(server_address);
recvfrom(sockfd, &ch, 1, 0, (struct sockaddr *)&server_address, &server_len);

printf("char from server=%c\n", ch);
close(sockfd);

exit(0);

}





kann mir jemand helfen?

Schöne Grüße
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
20.05.2003, 13:54 Uhr
virtual
Sexiest Bit alive
(Operator)


Also erstmal solltest Du dir mal überlegen, daß alle socket Funktionen Fehlercodes zurückliefern, die Fragst Du an keiner Stelle in der Schleife ab und auch nicht errno, was Dier ggf. auch aufschluß über das Problem geben könnte.

Dann ist es auch ein Frommer Wunsch zu glauben, daß man ein TCP Programm einfach auf UDP umstellen kann. Solange Du nur über das Loopback Device (127.0.0.1) arbeitest oder in einem Netzwerk ohne Router usw. arbeitest, mag deine UDP Umsetzung ja noch halbwegs klappen. Aber dadurch daß UDP connectionless arbeitet, kann es sein, daß Daten doppelt oder garnicht ankommen, oder einfach in einer anderen Reihenfolge, als Du sie losgeschickt hast. Ein adäqute Umsetzung von TCP -> UDP ist daher mit deutlich mehr Aufwand verbunden, als Dein Programm bisher erkennen läßt.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
20.05.2003, 14:14 Uhr
~arkantos
Gast


Mein sendto beim server liefert -1 zurück, wieso?

Die Umstellung müsste klappen, da ich nur über lokal-loop gehen will.


grüße arkantos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
20.05.2003, 14:39 Uhr
virtual
Sexiest Bit alive
(Operator)



Zitat:
~arkantos postete
Mein sendto beim server liefert -1 zurück, wieso?


Welchen Wert liefert den errno? schreib doch mal sowas:

C++:
if (sendto(server_sockfd, &ch, 1, 0, (struct sockaddr *)&client_address, client_len)!=1)
{
   printf("Fehler bei sendto: %s (%d).\n", strerror(errno), errno);
}


--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
20.05.2003, 15:14 Uhr
~arkantos
Gast


dann kommt errno undeclared...

muss ich da noch ne bibliothek einbinden?


Grüße arkantos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ GNU/Linux ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: