Solved

Connection and Winsock

Posted on 2000-03-13
18
1,011 Views
Last Modified: 2013-12-03
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
Comment
Question by:laeuchli
  • 11
  • 7
18 Comments
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
 
LVL 5

Author Comment

by:laeuchli
Comment Utility
Adjusted points from 20 to 50
0
 
LVL 5

Author Comment

by:laeuchli
Comment Utility
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
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
 
LVL 5

Author Comment

by:laeuchli
Comment Utility
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
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
 
LVL 5

Author Comment

by:laeuchli
Comment Utility
1.1.1.1 Is the right address, and the bind is the problem, not the connect. Bind fails.
0
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 3

Expert Comment

by:MDarling
Comment Utility
bind fails because you are putting 1.1.1.1

try it, with INADDR_ANY instead.

regards,
Mike.
0
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
 
LVL 5

Author Comment

by:laeuchli
Comment Utility
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
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
 
LVL 5

Author Comment

by:laeuchli
Comment Utility
Ok, that did the trick. But I have one question. Why did this make it work?
 
    memset(&Sa,0,sizeof(sockaddr_in));
   
0
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
 
LVL 5

Author Comment

by:laeuchli
Comment Utility
ok, you have earned the points.  Thank you.
Go ahead and answer.
0
 
LVL 3

Accepted Solution

by:
MDarling earned 50 total points
Comment Utility
cheers,
Mike
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now