Sign in to follow this  
Joesavage1

Networking in C++

Recommended Posts

Hi, Basically me and my friends want to make a game, and I thought if we're gonna make it we may aswell do it properly in C++. Since I only know a bit of Win32 C++ (Im still reading 'Windows game programming for dummies' which is helping alot), basically I want to know how to to the whole networking bit; So I was thinking I should make a chatroom or a simple server/client connection to figure out the whole networking thing (The rest of the book im reading (and some other books) will help out with the other parts a bit). Does anyone know how I can create this Client/Server connection? I looked a bit at winsock and some other thing, but no one really described how I got the header files and how I acctually used the functions or anything, which kinda rules them out as options until I get some idea on how to use them.. Thanks In Advance, Joe

Share this post


Link to post
Share on other sites
Quote:
Original post by Joesavage1
Basically me and my friends want to make a game, and I thought if we're gonna make it we may aswell do it properly in C++.

There's plenty of easier, 'proper' alternatives to C++ nowadays, ya know?

Quote:
Does anyone know how I can create this Client/Server connection?
I looked a bit at winsock and some other thing, but no one really described how I got the header files and how I acctually used the functions or anything, which kinda rules them out as options until I get some idea on how to use them..

Have you checked the Forum FAQ, namely question #1? There's plenty of good information and links for general questions like this there.

Share this post


Link to post
Share on other sites
Quote:
Quote:
Original post by Joesavage1
Basically me and my friends want to make a game, and I thought if we're gonna make it we may aswell do it properly in C++.

There's plenty of easier, 'proper' alternatives to C++ nowadays, ya know?



Yeah, but I think we all know C++ is the mainly used. Also I know quite a bit of C++ so it seemed the right decision..


Quote:
Quote:
Does anyone know how I can create this Client/Server connection?
I looked a bit at winsock and some other thing, but no one really described how I got the header files and how I acctually used the functions or anything, which kinda rules them out as options until I get some idea on how to use them..

Have you checked the Forum FAQ, namely question #1? There's plenty of good information and links for general questions like this there.




Ah, I look a bit of an idiot now; Thanks, Ill read through and if I have any other difficulty Ill post it.


Share this post


Link to post
Share on other sites
Hm. Ive had a read through many, MANY pages of tutorials on how to do this but they all seem to really rush into it, and I dont really understand what does what etc.

I would really appreciate it if someone posted some winsock sending and receiving messages code (preferably heavily commented)..



Please Help,


Thanks In Advance,



Joe

Share this post


Link to post
Share on other sites
These two are a bit at odds with each other:
Quote:
I would really appreciate it if someone posted some winsock sending and receiving messages code (preferably heavily commented)..

Quote:
Also I know quite a bit of C++ so it seemed the right decision..


Winsock, or sockets in general, are just an API. There is really not much to them. There is a code stanza to initialize it, then there are socket(), bind(), recv(), send() and select().

The order in which they are put has a reason, but can be just followed blindly. The tutorials haven't really changed in last 20 years, since the interface hasn't changed since then.

The "modern C++" alternative is boost asio, the middle ground is ACE, but I doubt those would be clearer.

I'm not really sure what the actual IP networking reading materials are, usually these are provided by various network programming courses, but they tend to cover much more than just dealing with connections, and tend to be somewhat OS-biased, since there is usually some overlap between kernel and networking.

Share this post


Link to post
Share on other sites
Quote:

There is a code stanza to initialize it, then there are socket(), bind(), recv(), send() and select().


Can you link me to one, or give an example please? (sorry for being such a pain, I just really dont understand it (im sure it'll just click into place when I figure it out).


Quote:
I'm not really sure what the actual IP networking reading materials are, usually these are provided by various network programming courses, but they tend to cover much more than just dealing with connections, and tend to be somewhat OS-biased, since there is usually some overlap between kernel and networking.


Im only really bothered about Windows to be honest.. (I shouldn't really rule the other people out, but Windows is the most popular OS (as im sure we all know)).

Share this post


Link to post
Share on other sites
Quote:
Original post by Joesavage1
Quote:

There is a code stanza to initialize it, then there are socket(), bind(), recv(), send() and select().


Can you link me to one, or give an example please? (sorry for being such a pain, I just really dont understand it (im sure it'll just click into place when I figure it out).


MSDN Winsock Reference

Share this post


Link to post
Share on other sites
Quote:
Original post by Joesavage1

Can you link me to one, or give an example please? (sorry for being such a pain, I just really dont understand it (im sure it'll just click into place when I figure it out).


This one is in FAQ (Q1) as well, along with many more.

Share this post


Link to post
Share on other sites
Ok so I got this far:

#include <iostream>
#include <winsock2.h>
using namespace std;



int main(){

WSADATA WsaDat; //For initialization
if (WSAStartup(MAKEWORD(1, 1), &WsaDat) != 0) //Worked?
{
cout << "WSA initialization failed." << endl;
}

SOCKET Socket; //Socket
Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET) //Worked?
{
cout << "Socket creation failed." << endl;
}

//We want to use port 50
SockAddr.sin_port = 50;

//We want an internet type connection (TCP/IP)
SockAddr.sin_family = AF_INET;

//We want to listen on IP address 127.0.0.1
SockAddr.sin_addr.S_un.S_un_b.s_b1 = 127;
SockAddr.sin_addr.S_un.S_un_b.s_b2 = 0;
SockAddr.sin_addr.S_un.S_un_b.s_b3 = 0;
SockAddr.sin_addr.S_un.S_un_b.s_b1 = 1;

//Ok all the information is set, lets bind()
if (bind(Socket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)//Worked?
{
cout << "Attempt to bind failed." << endl;
}


system("PAUSE");
return 0;
}



However Ive started getting some errors and I dont know why.. (I havent even got to the sending and receiving bit yet *sad face*)


Please Help,

Thanks In Advance,

Joe

EDIT: Forgot to post the errors :S.
Here they are:


1>------ Build started: Project: ConsoleNetworkingTest, Configuration: Debug Win32 ------
1>Compiling...
1>ConsoleNetworkingTest.cpp
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(23) : error C2065: 'SockAddr' : undeclared identifier
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(23) : error C2228: left of '.sin_port' must have class/struct/union
1> type is ''unknown-type''
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(26) : error C2065: 'SockAddr' : undeclared identifier
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(26) : error C2228: left of '.sin_family' must have class/struct/union
1> type is ''unknown-type''
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(29) : error C2065: 'SockAddr' : undeclared identifier
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(29) : error C2228: left of '.sin_addr' must have class/struct/union
1> type is ''unknown-type''
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(29) : error C2228: left of '.S_un' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(29) : error C2228: left of '.S_un_b' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(29) : error C2228: left of '.s_b1' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(30) : error C2065: 'SockAddr' : undeclared identifier
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(30) : error C2228: left of '.sin_addr' must have class/struct/union
1> type is ''unknown-type''
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(30) : error C2228: left of '.S_un' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(30) : error C2228: left of '.S_un_b' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(30) : error C2228: left of '.s_b2' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(31) : error C2065: 'SockAddr' : undeclared identifier
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(31) : error C2228: left of '.sin_addr' must have class/struct/union
1> type is ''unknown-type''
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(31) : error C2228: left of '.S_un' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(31) : error C2228: left of '.S_un_b' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(31) : error C2228: left of '.s_b3' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(32) : error C2065: 'SockAddr' : undeclared identifier
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(32) : error C2228: left of '.sin_addr' must have class/struct/union
1> type is ''unknown-type''
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(32) : error C2228: left of '.S_un' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(32) : error C2228: left of '.S_un_b' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(32) : error C2228: left of '.s_b1' must have class/struct/union
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(35) : error C2065: 'SockAddr' : undeclared identifier
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(35) : error C2065: 'SockAddr' : undeclared identifier
1>c:\users\user\documents\visual studio 2008\projects\consolenetworkingtest\consolenetworkingtest\consolenetworkingtest.cpp(35) : error C2070: ''unknown-type'': illegal sizeof operand
1>Build log was saved at "file://c:\Users\user\Documents\Visual Studio 2008\Projects\ConsoleNetworkingTest\ConsoleNetworkingTest\Debug\BuildLog.htm"
1>ConsoleNetworkingTest - 27 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

[Edited by - HiddenHaxor on February 22, 2010 11:00:54 AM]

Share this post


Link to post
Share on other sites
In addition, use memset to zero out the address structure before filling it, as unused fields should be zero. Also, I would recommend using .sin_addr.s_addr = INADDR_ANY for the address, which will allow connections to any appropriate address.

Share this post


Link to post
Share on other sites
Quote:
Original post by Joesavage1
I didnt declare it, the tutorial didnt say too..


Tutorials for WinSock will probably always assume you know C++ well enough, and won't show you such small details.
It should probably be SOCKADDR_IN SockAddr;.

Share this post


Link to post
Share on other sites
Awesome, thanks for your help guys.

Now I have this code and am only getting one error (Maybe its just anoter I have to declare a variable or something but I dont know):


#include <iostream>
#include <winsock2.h>
using namespace std;



int main(){

WSADATA WsaDat; //For initialization
if (WSAStartup(MAKEWORD(1, 1), &WsaDat) != 0) //Worked?
{
cout << "WSA initialization failed." << endl;
}

SOCKET Socket; //Socket
Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET) //Worked?
{
cout << "Socket creation failed." << endl;
}

SOCKADDR_IN SockAddr; //Socket Address

//We want to use port 50
SockAddr.sin_port = 50;

//We want an internet type connection (TCP/IP)
SockAddr.sin_family = AF_INET;

//Listen to any appropriate address
SockAddr.sin_addr.s_addr = INADDR_ANY;
//Ok all the information is set, lets bind()
if (bind(Socket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)//Worked?
{
cout << "Attempt to bind failed." << endl;
}


int RetVal = SOCKET_ERROR;
char String[] = "Hello";
while(RetVal == SOCKET_ERROR){
RetVal = recv(Socket, String, strlen(String) + 1, 0);
if ((RetVal == 0)||(RetVal == WSAECONNRESET)||(RetVal == WSAECONNABORT))
{
cout << "Connection closed at other end." << endl;
break;
}
}

system("PAUSE");
return 0;
}



Errors:
error C2065: 'WSAECONNABORT' : undeclared identifier



Also is it correct that if I had two exes, ones with the above code in, and the other with the firsts code but instead of recv says send that the receiving one would receive the sent message ("Hello" in this case), or is further code needed?(The tutorial trails off here..)

Share this post


Link to post
Share on other sites
Your error is all to do with C++ and nothing to do with sockets. If you aren't familiar enough with the language to deal with missing identifiers, you are going to struggle with the more high level logic problems that inevitably accompany complex programs.

I mean, did you even think to try Google first?

Share this post


Link to post
Share on other sites
Quote:
Your error is all to do with C++ and nothing to do with sockets. If you aren't familiar enough with the language to deal with missing identifiers, you are going to struggle with the more high level logic problems that inevitably accompany complex programs.


I am quite familiar with the language, However I'm not good at error handling (something I'm trying to get better at).


Quote:
I mean, did you even think to try Google first?


Yes, and I didn't get any results, clearly my search terms weren't as good as yours; Its all part of my learning how to interpret and handle errors.


Quote:

It seems the author of the tutorial I was reading ment WSAECONNABORTED instead of WSAECONNABORT. However now I have the following issues (linker related errors if I am correct):

1>ConsoleNetworkingTest.obj : error LNK2001: unresolved external symbol __imp__socket@12
1>ConsoleNetworkingTest.obj : error LNK2001: unresolved external symbol __imp__bind@12
1>ConsoleNetworkingTest.obj : error LNK2001: unresolved external symbol __imp__recv@16
1>ConsoleNetworkingTest.obj : error LNK2001: unresolved external symbol __imp__WSAStartup@8


Ill be trying to fix this via research, but if anyone could help that would be great!


EDIT: Now fixed via: #pragma comment(lib, "Ws2_32.lib") !


If I have any other problems Ill post,

Thx for the help so far,



Joe.

Share this post


Link to post
Share on other sites
Quote:
Did u even check RakNet or enet? it handles all the connection stuff(server-client) for you. yu just have to send data.


Nope. I dont want it to do everything for me, I want to do it myself (and Ive been told WinSock is the best way).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Im not sure If I'm doing this right but Im using the following codes for sending and receiving:



SENDING:

#include "stdafx.h"
#include <iostream>
#include <winsock2.h>
using namespace std;



int main(){

WSADATA WsaDat; //For initialization
if (WSAStartup(MAKEWORD(1, 1), &WsaDat) != 0) //Worked?
{
cout << "WSA initialization failed." << endl;
}

SOCKET Socket; //Socket
Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET) //Worked?
{
cout << "Socket creation failed." << endl;
}

SOCKADDR_IN SockAddr; //Socket Address

//We want to use port 50
SockAddr.sin_port = 50;

//We want an internet type connection (TCP/IP)
SockAddr.sin_family = AF_INET;

//Listen to any appropriate address
SockAddr.sin_addr.s_addr = INADDR_ANY;
//Ok all the information is set, lets bind()
if (bind(Socket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)//Worked?
{
cout << "Attempt to bind failed." << endl;
}


int RetVal = SOCKET_ERROR;
char String[] = "Hello";
while(RetVal == SOCKET_ERROR){
RetVal = send(Socket, String, strlen(String) + 1, 0);
if ((RetVal == 0)||(RetVal == WSAECONNRESET)||(RetVal == WSAECONNABORTED))
{
cout << "Connection closed at other end." << endl;
break;
}
}

system("PAUSE");
return 0;
}



RECEIVING:

#include "stdafx.h"
#include <iostream>
#include <winsock2.h>
using namespace std;



int main(){

WSADATA WsaDat; //For initialization
if (WSAStartup(MAKEWORD(1, 1), &WsaDat) != 0) //Worked?
{
cout << "WSA initialization failed." << endl;
}

SOCKET Socket; //Socket
Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET) //Worked?
{
cout << "Socket creation failed." << endl;
}

SOCKADDR_IN SockAddr; //Socket Address

//We want to use port 50
SockAddr.sin_port = 50;

//We want an internet type connection (TCP/IP)
SockAddr.sin_family = AF_INET;

//Listen to any appropriate address
SockAddr.sin_addr.s_addr = INADDR_ANY;
//Ok all the information is set, lets bind()
if (bind(Socket, (SOCKADDR *)(&SockAddr), sizeof(SockAddr)) == SOCKET_ERROR)//Worked?
{
cout << "Attempt to bind failed." << endl;
}


int RetVal = SOCKET_ERROR;
char String[] = "Hello";
while(RetVal == SOCKET_ERROR){
RetVal = recv(Socket, String, strlen(String) + 1, 0);
if ((RetVal == 0)||(RetVal == WSAECONNRESET)||(RetVal == WSAECONNABORTED))
{
cout << "Connection closed at other end." << endl;
break;
}
}

system("PAUSE");
return 0;
}



However when I try to run both at the same time I get a bind error on the one I run second (Im guessing because the other one is already bound to that port).

How do I get around this? Do I just give it a different port, or is it more complex than that?


Thanks In Advance,



Joe

Share this post


Link to post
Share on other sites
You shouldn't use bind on the client (sender), as it's not supposed to be bound to any specific local port. Instead use connect, passing the address of the server (you can't use INADDR_ANY here, but must use the server-addr, 127.0.0.1 works if you try it on the same computer). The server must already be running with listen and accept at this time, and connect will create a connection between two sockets, one on the client and one on the server.
You seem to be missing several steps in your code, for TCP.

You can also create SOCK_DGRAM sockets instead, which seems to be what your code is expecting. With this, you must use bind to different ports for both, and then specify the correct addresses (the address of the other program) in both, when using sendto to send data between them.

(all is simplified, one way of many)

Share this post


Link to post
Share on other sites
I once had to start developing with sockets as well, and i found a great source( at least i think it is great), with a little patience and understanding, you can start network programming within 2 weeks!

Source: http://www.tenouk.com/Winsock/Winsock2story.html

Share this post


Link to post
Share on other sites
I dont know about the others but I admire your persistence but your only being held back by your own ability.

You remind me of myself, I was a cut and paste coder who always ran to the community as soon as things didn't go right. One tip - dont skip steps, by this I mean go back to basics and get comfortable with the tools your using. Mastering the debugger will give you so much more confidence and you will be able to solve most problems.

Here's my suggestion. Get yourself a good C++ book and read it from cover to cover completing all of the examples as you go. Practice, practice practice! Look on the web for tutorials on how to use your compiler efficiently, there are even youtube videos on this. Once you have mastered these things the virtual world is your oyster!!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this