Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

recvfrom function 1

Status
Not open for further replies.

groove69

Programmer
May 25, 2004
9
US
Hello All,

The recvfrom function does not return the source address when using Microsoft Visual C/C++. I beleive I tried everything but nothing gives back a source address or a sockaddr*. Does anyone have any suggestions or samples of recvfrom working??
 
I thought the recvfrom function did return the address. This code has always worked for me in the past:

Code:
    // Attempt to read the given block of data.
    struct sockaddr_in addr;
    int addrLen;
    addrLen = sizeof (addr);
    std::vector<char> datagram (MAX_PACKET_SIZE);
    long result = recvfrom (m_socket, &datagram[0], MAX_PACKET_SIZE, 0,
        (struct sockaddr *) &addr, &addrLen);

    // Handle any error result.
    if (result == SOCKET_ERROR)
    {
        switch (WSAGetLastError ())
        {
        // Map the non-blocking result code to zero bytes written.
        case WSAEWOULDBLOCK:
            result = 0;
            break;

        // Any other result is a legitimate error.
        default:
            throw runtime_error ("error in recvfrom");
        }
    }

    // Determine the host name and port number of the sender.
    port = ntohs (addr.sin_port);

    // Try to convert host IP address to host name.
    struct hostent *hostinfo = NULL;
    if (m_enableNameLookup)
    {
        hostinfo = gethostbyaddr ((char *) &addr.sin_addr,
            sizeof (addr.sin_addr), AF_INET);
        {
            if (hostinfo != NULL)
            {
                host = hostinfo->h_name;
            }
        }
    }
    if (hostinfo == NULL)
    {
        ostringstream buffer;
        buffer << (int) (((unsigned char *)
            &addr.sin_addr) [0]);
        buffer << '.';
        buffer << (int) (((unsigned char *)
            &addr.sin_addr) [1]);
        buffer << '.';
        buffer << (int) (((unsigned char *)
            &addr.sin_addr) [2]);
        buffer << '.';
        buffer << (int) (((unsigned char *)
            &addr.sin_addr) [3]);
        host = buffer.str ();
    }
 
MSDN - about WinSock recvfrom():

The from and fromlen parameters are ignored for SOCK_STREAM sockets.
...
If from is non-zero, and the socket is of type SOCK_DGRAM, the network address of the peer which sent the data is copied to the corresponding struct sockaddr. The value pointed to by fromlen is initialized to the size of this structure, and is modified on return to indicate the actual size of the address stored there.
...
If the from paramter is nonzero and the socket is not connection oriented, (type SOCK_DGRAM for example), the network address of the peer that sent the data is copied to the corresponding SOCKADDR structure. The value pointed to by fromlen is initialized to the size of this structure and is modified, on return, to indicate the actual size of the address stored in the SOCKADDR structure.


Verify the socket parameters...
 
The socket parameters are of SOCK_STREAM. But isnt there a way to determine where you are recieving data from with this socket parameter?? I would think recvfrom would tell you the ip address that sent you packets.
 
Try using
Code:
int getpeername ( SOCKET s, struct sockaddr FAR * name, int FAR * namelen );
Connected stream socket knows the other side of a connection...
 
Hey ArkM,


YOU ARE THE GREATEST!!!!!!!!!!!!!!!!!!!!!!!!
 
Ooh, that explains it. I thought you were calling recvfrom on a datagram socket...
 
Hey Teriviret,

I have a question for you. How exactly do you use the select statement?? I know it is suppose to tell you the status of your sockets. But if I have 3 remote clients connecting to one server socket and when I run the select to find out which socket to read, it(being the select function) overwrites the socket address spaces in the fd_array. If you try it, you will see exactly what I am saying.

Sorry for the misunderstanding on the other question.

Thanks
 
A socket is just a handle or pointer -- if you look in WinSock.h, it's defined thusly:

Code:
typedef UINT_PTR        SOCKET;

So it's okay if the SOCKET value is overwritten, as long as you keep another copy of the SOCKET somewhere safe.

I'm not sure what you mean by a socket address space. Do you mean the SOCKET value, the actual socket connection that it refers to, the client's IP address and port number, or something else?
 
WOW!!!!!!!!!!!!!!!

Well I understood the way you explained it but Microsoft doesnt make it that obvious.


THANKS A LOT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 
may i ask why you were trying to find the remote address of a connection-oriented socket? if it is a client socket (i.e. you initiated the TCP connection with connect()), then you had to specify the address/port. if it is a server socket (i.e. returned by accept()), then the remote address and port are filled by accept(). so, in all cases you should already know the address/port of a connection-oriented socket. was this socket returned by a DLL or some other called function that you don't have control over?
 
Hi Jorgander,

Yes it is true that you will get the remote address from the accept function. However, if I have 5 clients connect to one server port, how do I tell who is sending the server a message and who disconnected. Using the recv function, it only has the socket, buffer, and flags and no way to tell who sent the message. I thought the recvfrom function would give this info but if your socket parameter is SOCK_STREAM it will not work.
 
If you're using SOCK_STREAM then each time a client connects, you should call accept() and get a different socket, returned by the accept() call. The original socket should only be used for accepting new connections. Once a connection is made, use the new socket to talk to the client. So if you have 5 clients connect, you should have 6 sockets -- the original server socket plus 5 new client sockets.
 
I have another question. What is the best way to determine which client disconnected from your server socket?? Not sure how this would be done.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top