Network programming (C++)

Programming, for all ages and all languages.
Post Reply
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Network programming (C++)

Post 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.
This was supposed to be a cool signature...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post 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:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post 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â€
This was supposed to be a cool signature...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

and the accept() call?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post by Zacariaz »

probably, but where? (i hate to sond this noobish)
This was supposed to be a cool signature...
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post 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.
This was supposed to be a cool signature...
User avatar
B.E
Member
Member
Posts: 275
Joined: Sat Oct 21, 2006 5:29 pm
Location: Brisbane Australia
Contact:

Post 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
Image
Microsoft: "let everyone run after us. We'll just INNOV~1"
User avatar
Zacariaz
Member
Member
Posts: 1069
Joined: Tue May 22, 2007 2:36 pm
Contact:

Post 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.
This was supposed to be a cool signature...
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post 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:
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post 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.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post 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.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
Post Reply