user1348950
user1348950

Reputation: 63

Get socket's IP address before accepting connection C++

I need to get the IP address of a connection to see if it has already connected previously (checking against a list of ips, if it has connected previously but isnt connected anymore, it will say offline). (using nonblocking sockets)

How can I get the IP without first accepting it.

///

    case FD_ACCEPT:
        int W;
        for(W = 0;W <= ListView_GetItemCount(GetDlgItem(HwND,IDC_IPLIST));W++){

So then im just gonna check the IP against the list view to see if it had connected before. If it has, I want to use the same socket number it was using last time.

This is how I'm accepting connections right now

        case FD_ACCEPT: 
        while(Client[F] != NULL)
        {
        F++;
        }
        Client[F]=accept(wParam,(LPSOCKADDR)&ServAdr,&AdrLen);
        break;

so to break it down...

I want to check incoming connections against an IP list of previous connections. This list will have the IP and whether its online/offline (connected/not connected). If it has connected before I want it to show Online when I accept the new connection, and use the same socket number it used last time instead of using a new one all together. If it hasn't I want it to be added to the list. (the list will have the socket number)

If this doesnt make much sense I'll try and clarify a bit more.

Upvotes: 2

Views: 3068

Answers (4)

Ben Voigt
Ben Voigt

Reputation: 283614

If you bind to a wildcard address (INADDR_ANY), then the IP address used for communication isn't determined until a connection comes in (it will be one from the interface the packets are passing through). The same listening socket can result in accepted connections on more than one IP address.

If you bind to a specific address, then you already know the address you bound to.

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 595329

What you are asking for cannot be done with accept(). You do not have access to a connection's information until after it has been accepted and a new SOCKET handle allocated. To get the connection info pre-acceptance, you have to use the callback functionality of WSAAccept() instead.

Either way, there is no way to reuse an existing SOCKET handle for a new connection. Each accepted connection must have its own unique SOCKET handle. You can certainly associate the new connection from a previously-seen IP with an existing slot in your ListView, though.

Upvotes: 2

Pavel Zhuravlev
Pavel Zhuravlev

Reputation: 2791

If by socket number you mean the number returned by accept(), you can't rely on it's value at all. I mean, if the remote host disconnects and connects again the value returned by accept() will most probably be different. It does not make sense to rely on this number.

If by socket number you mean the position in your array, you can assign the value returned by accept() to temporary variable:

SOCKET tmpSock;
sockaddr_in tmpAddr;
int namelen;
typedef struct { /*...*/ } TClient;
TClient Client[MAX_CLIENTS];
/*...*/
tmpSock = accept(/*...*/);
namelen = sizeof(tmpAddr);
getpeername(tmpSock, (sockaddr*)&tmpAddr,&namelen);
/*...*/
//looking for tmpAddr.sin_addr in your list and calculating
//the list position - F
/*...*/
Client[F].Socket = tmpSock;
Client[F].IsConnected = true;
Client[F].Address = tmpAddr.sin_addr;

Have in mind that after the listen() call the OS kernel will accept all incoming connection to the port/local IP set by you. It means that the connect() of remote host will return successfully whether you call accept() or not (provided you have space in listen queue). Calling accept() will only allow you to interact with the socket. It will not change the connection state seen by the remote host.

Upvotes: 1

Kind Contributor
Kind Contributor

Reputation: 18513

I'm not sure the is possible nor an efficient specification to achieve what you want. I would either:

  1. Accept any connection and then check the IP address, disconnecting connections which are not in the list

  2. (This probably isn't suitable for you) Configure an upstream firewall, such that only allowed IP addresses are allowed through.

Upvotes: 2

Related Questions