Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1021
  • Last Modified:

Connection and Winsock

hey, I am trying to learn to use winsock. I have a short sample app(code below)That is supposed to display a message box if a app trys to connect. I can't seem to get it to work. Is there a error in this code or is something wrong with my app that is trying to connect. The ip is a valid ip on my lan.
#pragma comment( lib, "ws2_32.lib" )
#include <stdio.h>
#include<winsock2.h>
#include<windows.h>
struct sockaddr_in Sa;

void main( void )
{
      WSADATA m_WSAData;
    int nResult = 0;
    if( ( nResult = WSAStartup( 0x0002, &m_WSAData ) ) != 0 )
    {
        printf( "Winsock 2.0 not supported.\n" );
    }
 
    ::printf( "Winsock 2.0 supported.\n" );
 
    if( WSACleanup( ) == SOCKET_ERROR )
        printf( "Cleanup Problem!\n" );
      SOCKET s;
      s=socket(PF_INET,SOCK_DGRAM,0);
  Sa.sin_family=AF_INET;
      Sa.sin_addr.s_addr = inet_addr("1.1.1.1");
      Sa.sin_port=htons(13);
      bind(s,(struct sockaddr *)&Sa,sizeof(Sa));
      listen(s,10);
      WSAEVENT m_WSA;
      LPWSANETWORKEVENTS m_test;
      m_WSA=WSACreateEvent();
      WSAEventSelect(s, m_WSA,FD_ACCEPT);
      WSAEVENT EventArray[ 1 ];
      EventArray[0]= m_WSA;
      DWORD dwIamwaiting=WSAWaitForMultipleEvents(1,EventArray, FALSE, WSA_INFINITE, FALSE );
 
      switch(dwIamwaiting- WSA_WAIT_EVENT_0)
      {
      case 0:
            {
            while(WSAEnumNetworkEvents(s,m_WSA,m_test))
            {
            if(m_test->lNetworkEvents==FD_ACCEPT)
            {
            MessageBox(0,"Hello","hello",MB_OK);
            break;
            }
            }
            break;
            }
      }

}
0
laeuchli
Asked:
laeuchli
  • 11
  • 7
1 Solution
 
MDarlingCommented:
ok for starters why SOCK_DGRAM

thats a connectionless protocol.

try SOCK_STREAM instead.

secondly check all your return codes

bind will return none zero on error.

third why address 1.1.1.1

why not use
Address.sin_addr.s_addr=INADDR_ANY

regards,
Mike.
0
 
laeuchliAuthor Commented:
Adjusted points from 20 to 50
0
 
laeuchliAuthor Commented:
and here is my client code. I have changed the bind code to return if it has errors or not and it does. Could you me fix it? I think that if I can fix the client I will have a good shot at the server:
#pragma comment( lib, "ws2_32.lib" )
#include <stdio.h>
#include<winsock2.h>
#include<windows.h>
#include<iostream.h>
struct sockaddr_in Sa;

void main( void )
{
      WSADATA m_WSAData;
    int nResult = 0;
    if( ( nResult = WSAStartup( 0x0002, &m_WSAData ) ) != 0 )
    {
        printf( "Winsock 2.0 not supported.\n" );
    }
 
    ::printf( "Winsock 2.0 supported.\n" );
 
    if( WSACleanup( ) == SOCKET_ERROR )
        printf( "Cleanup Problem!\n" );
      SOCKET s;
      s=socket(PF_INET,SOCK_STREAM,0);
        Sa.sin_addr.s_addr =inet_addr("1.1.1.1");
      int z=bind(s,(struct sockaddr *)&Sa,sizeof(Sa));
      if(z!=0)
      {
      MessageBox(0,"Error","Error",MB_OK);
      }
      connect(s,(struct sockaddr *)&Sa,sizeof(Sa));
      int i;
      cin>>i;

}
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
MDarlingCommented:
don't call WSACleanup() until the end of your program - heres some example code
from a simple client...

int main()
{
    InitSocks();
    SOCKET s=socket(PF_INET,SOCK_STREAM,0);

    sockaddr_in saddr;
    memset(&saddr,0,sizeof(sockaddr_in));
    saddr.sin_family=PF_INET;

    if(bind(s,reinterpret_cast<sockaddr *>(&saddr),sizeof(sockaddr_in)))
    {
        cerr << "Couldn't bind\n";
        return -1;
    }

      struct sockaddr_in Address;
      Address.sin_family=PF_INET;
      Address.sin_addr.s_addr=inet_addr("127.0.0.1");
      Address.sin_port=htons(8080);
    if(connect(s,(sockaddr *)&Address,sizeof(sockaddr_in)))
    {
        cerr << "Couldn't connect\n";
        return -1;
    }

    char *szCmd="GET /pic.gif HTTP/1.0\r\n\r\n";
    if(send(s,szCmd,strlen(szCmd),0L)==SOCKET_ERROR)
    {
        closesocket(s);
    }
    else
    {
        char szBuff[256];

        int n=recv(s,szBuff,sizeof(szBuff)-1,0);
        while(n!=SOCKET_ERROR && n!=0)
        {
            szBuff[n]=0;
            cout << szBuff;
            cout.flush();
            n=recv(s,szBuff,sizeof(szBuff)-1,0);
        }
        cout.flush();
    }

    cout << "Connected.\n";

    return 0;
}


regards,
Mike.
0
 
MDarlingCommented:
Here's my InitSocks function...


bool InitSocks()
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD( 2, 2 );
    err = WSAStartup( wVersionRequested, &wsaData );
    if ( err != 0 )
    {
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */    
        return false;
    }
    /* Confirm that the WinSock DLL supports 2.2.*/
    /* Note that if the DLL supports versions greater    */
    /* than 2.2 in addition to 2.2, it will still return */
    /* 2.2 in wVersion since that is the version we      */
    /* requested.                                        */
    if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
    {
        /* Tell the user that we could not find a usable */
        /* WinSock DLL.                                  */    
        WSACleanup( );
        return false;
    }
    return true;
}


regards,
Mike.
0
 
laeuchliAuthor Commented:
Ok, I changed my code to :
#pragma comment( lib, "ws2_32.lib" )
#include <stdio.h>
#include<winsock2.h>
#include<windows.h>
#include<iostream.h>
struct sockaddr_in Sa;
struct sockaddr_in Sa2;
void main( void )
{
      WSADATA m_WSAData;
    int nResult = 0;
    if( ( nResult = WSAStartup( 0x0002, &m_WSAData ) ) != 0 )
    {
        printf( "Winsock 2.0 not supported.\n" );
    }
 
    ::printf( "Winsock 2.0 supported.\n" );
 
         SOCKET s;
      s=socket(PF_INET,SOCK_STREAM,0);
        int z=bind(s,(struct sockaddr *)&Sa,sizeof(Sa));
      if(z!=0)
      {
      MessageBox(0,"Error","Error",MB_OK);
      }
      Sa2.sin_family=PF_INET;
    Sa2.sin_addr.s_addr=inet_addr("1.1.1.1");
      connect(s,(struct sockaddr *)&Sa2,sizeof(Sa2));
      int i;
      cin>>i;
WSACleanup( );
and still no go. I don't want to just copy your code untill I know the problem with my old stuff. Thanks for the hepl.
0
 
MDarlingCommented:
is your server actually on the address
1.1.1.1 (is seems very unlikely)

if you are running the 2 apps on the
same machine then use the loopback
address 127.0.0.1

here's an easy way to check your server

run telnet
select connect
enter 127.0.0.1 as Host Name
enter 13 as port (and btw that is very low! it should be above 1024)

and click ok
if your server is working it should
tell you you got a connect...

regards,
Mike.
0
 
laeuchliAuthor Commented:
1.1.1.1 Is the right address, and the bind is the problem, not the connect. Bind fails.
0
 
MDarlingCommented:
Hi,

here's some mods to your code...

#pragma comment( lib, "ws2_32.lib" )
#include <stdio.h>
#include<winsock2.h>
#include<windows.h>
struct sockaddr_in Sa;

void main( void )
{
    WSADATA m_WSAData;
    int nResult = 0;
    if( ( nResult = WSAStartup( 0x0002, &m_WSAData ) ) != 0 )
    {
        printf( "Winsock 2.0 not supported.\n" );
        return;
    }

    ::printf( "Winsock 2.0 supported.\n" );

    SOCKET s;
    s=socket(PF_INET,SOCK_STREAM,0);        // change here
    Sa.sin_family=AF_INET;
    Sa.sin_addr.s_addr = INADDR_ANY;        // change here
    Sa.sin_port=htons(13);
    if(bind(s,(struct sockaddr *)&Sa,sizeof(Sa)))
    {
        printf("Error in bind!\n");
        return;
    }
    if(listen(s,10))
    {
        printf("Error in listen!\n");
        return;
    }
    WSAEVENT m_WSA;
    WSANETWORKEVENTS m_test; // change here
    m_WSA=WSACreateEvent();
    WSAEventSelect(s, m_WSA,FD_ACCEPT);
    WSAEVENT EventArray[ 1 ];
    EventArray[0]= m_WSA;
    DWORD dwIamwaiting=WSAWaitForMultipleEvents(1,EventArray, FALSE, WSA_INFINITE, FALSE );

    switch(dwIamwaiting- WSA_WAIT_EVENT_0)
    {
        case 0:
        {
            while(WSAEnumNetworkEvents(s,m_WSA,&m_test)) // change here
            {
                if(m_test.lNetworkEvents==FD_ACCEPT)
                {
                    MessageBox(0,"Hello","hello",MB_OK);
                    break;
                }
            }
            break;
        }
        break;
    }
}


mod1: must be SOCK_STREAM to get a connection
mod2: you don't care what your address is its always going to be your machines IP address
mod3: you only had a pointer before - now you have the structure itself
mod4: taking the address of the structure to get the pointer


regards,
Mike.
0
 
MDarlingCommented:
bind fails because you are putting 1.1.1.1

try it, with INADDR_ANY instead.

regards,
Mike.
0
 
MDarlingCommented:
hi laeuchli, couple more q's:

what exactly do you want your server to do?

why aren't you using accept to accept new connections?

regards,
Mike.
0
 
laeuchliAuthor Commented:
I am trying to get my client work right first. I posted the client code, and am try to figure out the problem. That's the question. The server is only supposed to put up a messagebox when a client trys to connect. I will work on that after the client works.
0
 
MDarlingCommented:
how can you tell if your client is
working is your server isn't?

You can't connect to address 1.1.1.1
It doesn't exist.
You have to connect to 127.0.0.1 - the
loopback test address or your machines
IP address.

Also as a client you can't bind to the address 1.1.1.1
You must use INADDR_ANY to let TCP/IP
sort it out for you.

Have you tried this?

regards,
Mike.

0
 
MDarlingCommented:
ok here is your code for both server
and client modified

the client will connect to the server

i don't really understand why your'e using
the WSAEvent stuff instead of accept

but here it is...

// START OF SERVER CODE

#pragma comment( lib, "ws2_32.lib" )
#include <stdio.h>
#include<winsock2.h>
#include<windows.h>
struct sockaddr_in Sa;

void main( void )
{
    WSADATA m_WSAData;
    int nResult = 0;
    if( ( nResult = WSAStartup( 0x0002, &m_WSAData ) ) != 0 )
    {
        printf( "Winsock 2.0 not supported.\n" );
        return;
    }

    ::printf( "Winsock 2.0 supported.\n" );

    SOCKET s;
    s=socket(PF_INET,SOCK_STREAM,0);        // change here
    Sa.sin_family=AF_INET;
    Sa.sin_addr.s_addr = INADDR_ANY;        // change here
    Sa.sin_port=htons(13);
    if(bind(s,(struct sockaddr *)&Sa,sizeof(Sa)))
    {
        printf("Error in bind!\n");
        return;
    }
    if(listen(s,10))
    {
        printf("Error in listen!\n");
        return;
    }
    WSAEVENT m_WSA;
    WSANETWORKEVENTS m_test; // change here
    m_WSA=WSACreateEvent();
    WSAEventSelect(s, m_WSA,FD_ACCEPT);
    WSAEVENT EventArray[ 1 ];
    EventArray[0]= m_WSA;
    DWORD dwIamwaiting=WSAWaitForMultipleEvents(1,EventArray, FALSE, WSA_INFINITE, FALSE );

    switch(dwIamwaiting- WSA_WAIT_EVENT_0)
    {
        case 0:
        {
            while(WSAEnumNetworkEvents(s,m_WSA,&m_test)) // change here
            {
                if(m_test.lNetworkEvents==FD_ACCEPT)
                {
                    MessageBox(0,"Hello","hello",MB_OK);
                    break;
                }
            }
            break;
        }
        break;
    }
}


// END OF SERVER CODE

// START OF CLIENT CODE

#pragma comment( lib, "ws2_32.lib" )
#include <stdio.h>
#include<winsock2.h>
#include<windows.h>
#include<iostream.h>
struct sockaddr_in Sa;
struct sockaddr_in Sa2;
void main( void )
{
    WSADATA m_WSAData;
    int nResult = 0;
    if( ( nResult = WSAStartup( 0x0002, &m_WSAData ) ) != 0 )
    {
        printf( "Winsock 2.0 not supported.\n" );
    }

    ::printf( "Winsock 2.0 supported.\n" );

    SOCKET s;
    s=socket(PF_INET,SOCK_STREAM,0);

    /*Change Here*/
    memset(&Sa,0,sizeof(sockaddr_in));
    Sa.sin_family=PF_INET;
   
    int z=bind(s,(struct sockaddr *)&Sa,sizeof(Sa));
    if(z!=0)
    {
       MessageBox(0,"Couldn't bind","Error",MB_OK);
    }
    Sa2.sin_family=PF_INET;
    Sa2.sin_addr.s_addr=inet_addr("127.0.0.1");
    Sa2.sin_port=htons(13);
    if(connect(s,(struct sockaddr *)&Sa2,sizeof(Sa2))==SOCKET_ERROR)
    {
        MessageBox(0,"Couldn't connect","Error",MB_OK);
    }
    int i;
    cin>>i;
    WSACleanup( );
}

// END OF CLIENT CODE


regards,
Mike.
0
 
laeuchliAuthor Commented:
Ok, that did the trick. But I have one question. Why did this make it work?
 
    memset(&Sa,0,sizeof(sockaddr_in));
   
0
 
MDarlingCommented:
This sets the fields values to 0
This tells the winsock api that it is
free to choose appropriate values for you.
I suspect that previously the structure
was full of garbage which it was trying
to make sense of.

For the address: 0 = INADDR_ANY and so
the bind works find.

regards,
Mike.
0
 
laeuchliAuthor Commented:
ok, you have earned the points.  Thank you.
Go ahead and answer.
0
 
MDarlingCommented:
cheers,
Mike
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 11
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now