Page 1 of 1

Network programming (C++)

Posted: Mon Nov 26, 2007 9:29 pm
by Zacariaz
I have started reading up on network programming and i have found a really good tutorial and it is going fine i'd say.

However i have one problem and one question.

The problem is with some sample code:

Code: Select all

#include <windows.h>
#include <winsock.h>

SOCKET s;
WSADATA w;

//LISTENONPORT – Listens on a specified port for incoming connections 
//or data
int ListenOnPort(int portno)
{
    int error = WSAStartup (0x0202, &w);   // Fill in WSA info

    if (error)
    {
        return false; //For some reason we couldn't start Winsock
    }

    if (w.wVersion != 0x0202) //Wrong Winsock version?
    {
        WSACleanup ();
        return false;
    }

    SOCKADDR_IN addr; // The address structure for a TCP socket

    addr.sin_family = AF_INET;      // Address family
    addr.sin_port = htons (portno);   // Assign port to this socket

    //Accept a connection from any IP using INADDR_ANY
    //You could pass inet_addr("0.0.0.0") instead to accomplish the 
    //same thing. If you want only to watch for a connection from a 
    //specific IP, specify that //instead.
    addr.sin_addr.s_addr = htonl (INADDR_ANY);  

    s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); // Create socket

    if (s == INVALID_SOCKET)
    {
        return false; //Don't continue if we couldn't create a //socket!!
    }

    if (bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
    {
       //We couldn't bind (this will happen if you try to bind to the same  
       //socket more than once)
        return false;
    }

    //Now we can start listening (allowing as many connections as possible to  
    //be made at the same time using SOMAXCONN). You could specify any 
    //integer value equal to or lesser than SOMAXCONN instead for custom 
    //purposes). The function will not //return until a connection request is 
    //made
    listen(s, SOMAXCONN);

    //Don't forget to clean up with CloseConnection()!
}
It should hang until a connection request is made, however i exits emidiately, no matter which port i specify.

NB. I have linked the "libws2_32.a" and it compiles without warnings of any kind.

The idea was then to test it with telnet 127.0.0.1:1234 but ofcourse i havent gotten that far.


I have another question though.
I was planning on allso testing this with an outside source, so i started up pokerstars and did a "netstat" to find out which port to listen on.

i got this result:
localadress:rand
remoteadress:const

by rand i mean that the port changes from time to time and by const i mean that its the same port every time.

As far a i know i should listen on the port specified at the local adress, but that confuses me a bit as it changes, which basicly mean that i'd have to determine which port to listen on every time i wanted to do so. To me it seems that i should listen on the other port instead, but that conflicts with what im told here.

Which is the correct one?


Allso what do you do when one or more key keep falling of your laptop keyboard? its getting really annoying! :cry:

Anyway, thanks in advance.

Edit:
1 ...\main.cpp [Warning] `nul.gcda' is not a gcov data file

I have been googling around and have faound lots about this warning, only problem being that nobody seems to know what it means.

Posted: Tue Nov 27, 2007 1:30 am
by Combuster
MSDN wrote:To accept connections, a socket is first created with the socket function and bound to a local address with the bind function. A backlog for incoming connections is specified with listen, and then the connections are accepted with the accept function. Sockets that are connection oriented, those of type SOCK_STREAM for example, are used with listen. The socket s is put into passive mode where incoming connection requests are acknowledged and queued pending acceptance by the process.
In other words, you forgot a step :wink:

Posted: Tue Nov 27, 2007 1:44 am
by Zacariaz
ya, i read some more and figured this much, but i have trouble determining what excactly im missing. Here is what i have right now:

Code: Select all

//CONNECT TO REMOTE HOST (CLIENT APPLICATION)
//Include the needed header files.
//Don’t forget to link libws2_32.a to your program as well
#include <windows.h>
#include <winsock.h>
#include <iostream>
SOCKET s;
WSADATA w;

//CONNECTTOHOST – Connects to a remote host
bool ConnectToHost(int PortNo, char* IPAddress)
{
//Start up Winsock…
WSADATA wsadata;

int error = WSAStartup(0x0202, &wsadata);

//Did something happen?
if (error)
	return false;

//Did we get the right Winsock version?
if (wsadata.wVersion != 0x0202)
{
	WSACleanup(); //Clean up Winsock
	return false;
}

//Fill out the information needed to initialize a socket…
SOCKADDR_IN target; //Socket address information

target.sin_family = AF_INET; // address family Internet
target.sin_port = htons (PortNo); //Port to connect on
target.sin_addr.s_addr = inet_addr (IPAddress); //Target IP

s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); //Create socket
if (s == INVALID_SOCKET)
{
    return false; //Couldn’t create the socket
}
 	
	
//Try connecting...
if (connect(s, (SOCKADDR *)&target, sizeof(target)) == SOCKET_ERROR)
{
  return false; //Couldn’t connect
}
else
	return true; //Success
}

//CLOSECONNECTION – shuts down the socket and closes any connection on it
void CloseConnection ()
{
	//Close the socket if it exists
	if (s)
		closesocket(s);

	WSACleanup(); //Clean up Winsock
}


//LISTENONPORT – Listens on a specified port for incoming connections //or data
int ListenOnPort(int portno)
{
int error = WSAStartup (0x0202, &w);   // Fill in WSA info
 
if (error)
{
return false; //For some reason we couldn’t start Winsock
}
if (w.wVersion != 0x0202) //Wrong Winsock version?
{
WSACleanup ();
return false;
}

SOCKADDR_IN addr; // The address structure for a TCP socket

addr.sin_family = AF_INET;      // Address family
addr.sin_port = htons (portno);   // Assign port to this socket

//Accept a connection from any IP using INADDR_ANY
//You could pass inet_addr(“0.0.0.0â€

Posted: Tue Nov 27, 2007 1:50 am
by Combuster
and the accept() call?

Posted: Tue Nov 27, 2007 1:55 am
by Zacariaz
probably, but where? (i hate to sond this noobish)

Posted: Tue Nov 27, 2007 2:42 am
by Zacariaz
dammit, i read and read and read and read, it all seems to make sence, and yet nothing is working.

If anyone know of a "good" winsock tutorial, please let me know.

Posted: Tue Nov 27, 2007 4:04 am
by B.E
Zacariaz wrote:dammit, i read and read and read and read, it all seems to make sence, and yet nothing is working.

If anyone know of a "good" winsock tutorial, please let me know.
I someone who knows a lot of winsock tutorials, his name is Google.

Anyway enough of that, try WinSock Tutorial

Posted: Tue Nov 27, 2007 4:37 am
by Zacariaz
Google? never heard of it. (end of sarkasm)
That is not the most welcome responce when you have used the last 12 hours googlin'.

The link you provide i have allready looked at, and though it seems nice, it is not very long, has allmost no comments and lack a complete working example.

Posted: Tue Nov 27, 2007 9:17 am
by Brynet-Inc
I personally think Beej's guide is good..

The tutorials could easily be adapted to "WinSock".

http://www.beej.us/guide/bgnet/output/h ... index.html

EDIT: This may be a wild guess, but maybe if you try calling ListenOnPort() before ConnectToHost() ? :roll:

Posted: Tue Nov 27, 2007 10:57 am
by Combuster
I spent one minute on MSDN to find the quote I posted above.

listen() does *NOT* block. It will only open up a socket for incoming connections.

accept() is the call that DOES block. it returns the socket handle for the new connection.

Posted: Tue Nov 27, 2007 7:36 pm
by mystran
Howto listen to inbound connections, short version:

- create a socket using the socket() call
- bind said socket to some address using bind()
- tell the system that we are listening to connections by using listen()
- wait for a new incoming connection using accept()
- loop

Now, if you think of it, you connect by doing socket()->bind()->connect() and then read()/write()... if you think of a socket accepting connections as a waiting queue for the new connections, then listen() "connects" you to such a queue, and accept() is call for read()ing new connections from the queue.

And yes, I know bind() is optional when making outbound connections.

I've never written a single WinSock app, though I've ported some socket code of mine from Unix to Windows. You can basicly use any TCP/IP tutorial even if it's for Unix, as only things different in Windows is CloseConnection() instead of close(), and WSAStartUp() to get WinSock up and running.