08-05-2010, 12:03 PM
This comes with permission from mach to post this. He made this a long time ago.
----------------------
Winsock 2 C++ Tutorial
----------------------
Winsockets are what computers use to connect two applications over the internet. Today I will be showing you how to make a simple "Server" and "Client" application.
Before we get started, I will assume you have/know the following.
1) Basic C++ Experience
2) Basic Computer terminology
3) Basic Networking Terminology
2) I use Dev-C++, so I assume you do to!
~Linking the Library~
Before you even start diving into the coding, you must link the appropriate library to use Winsock, or your going to get a load of linking errors.
To do this, you simply create a new console application, name it whatever you want (I use client or server)
WARNING:
What I do right now only applys to Dev-C++, if you try it with VC++ or any other IDE, your going to get lost.
Once you have your new project created, goto "project" menu.
Now goto project options.
Goto the parameters tab.
Click "Add Library or Object".
Now locate your Dev-Cpp folder (probably in the C:/ drive)
Now locate the "lib" folder.
Now scroll down until you find the library called "libws2_32.a". Double click on it.
Now press okay.
============================
~Getting the Server Started~
============================
Now that you have linked the correct library, lets get the right headers in.
Hopefully thats self-explanatory.
Now lets startup the winsocket. For this we use the following lines of code;
'WSAGetLastError()' does exactly what it says. It returns the error number that occured. If you do encounter an error, look up the error code on MSDN (MicroSoft Directors Network)
If everything works just right, you get the cheery message, "WSAStartup Successful!".
Now that you started the Winsock we need to create a socket. This can be by the following code;
Lets take a look at the Socket parameters.
SOCKET mysock | Basically makes a socket named 'mysock'.
socket(AF_INET, SOCK_STREAM, 0) | This is divided into 3 parameters.
1) Address Family
2) Connection type
3) Protocol
AF_INET calls for IPv4.
SOCK_STREAM calls for a reliable two-way connection with the server and client(s)
For the 3rd parameter, I just use '0'. You can look up alternatives on MSDN, but I will be just showing the most simplistic way.
Now that we have created our socket, we need to bind it. To do this we use the following code;
Okay, this is alot at first, but it gets really easy to remember after a few times of practicing.
To start binding it, you declare the "sockaddr_in" structure. The "anews" can be replaced with anything, as long as its not a reserved word.
You need to specify 3 things inside the structure.
1) Port
2) Connections to accept
3) Address Family
For the port we use "htons(80)". htons converts the number into network byte order. Basically it makes things easy.
INADDR_ANY will accept any connection being made to this socket. You can specify any connection, but for this example, we will be letting anyone in.
AF_INET specifys that we will be using the IPv4 address family. You can specify to use IPv6, but the entire code will need alot of changes in structure. (Well, maybe not, I haven't really looked into it, but I would assume big changes would be needed)
Now that we have binded our socket, its time to listen for connections.
Listen has only 2 parameters;
1) Socket
2) Max connections to be accepted
mysock is what I named my socket earlier, so I have to use that.
SOMAXCONN will make the socket accept its maximum connections possible before quitting.
Now that we are listening for connections, we need to accept the connections. To accept connections we must make another socket.
To do this we use the following lines of code;
Accept needs 3 parameters. For this tutorial, you only need to worry about one. You just need to specify your socket. For the other two, just set them as 'NULL'.
The next two requirements for the complete server is Send() & Recv(). We will go into that after we make the client.
~Getting the Client started~
You would start out the client the same as you would the server.
Make sure you make the client in an entirely seperate Project and be sure to link the libws2_32.a library.
Now this is where the familiarity ends. You need to connect to a socket, rather than bind to one.
To do this you use the same structure, sockaddr_in.
TO LARGE TO FIT IN ONE POST....SEE BELOW!
Not alot of changes really.
We specify to connect to our localhost here, (inet_addr("127.0.0.1")).
Now when putting the client on a different computer, you specify your IPv4. To get your IPv4 address, you open up your cmd, and type in "ipconfig /all" then it will tell you, just look for it.
=-=-=-=
WARNING:
If you put in your IPv4 address, make sure you port forward. I will not explian how to do that in this tutorial, just google and/or youtube it.
=-=-=-=
Now that we are connected we can finally concentrate on receiving and sending information between the two.
Lets switch our focus back to the Server application.
To send info across the internet, we must put the info into buffers.
Now to receive is about the samething...
They both have the same parameters as well;
1) Socket
2) Buffer
3) Buffer length
4) Flags (Lets just use zero and keep it simple)
Now after you send you data, and have no more to send, we need to close the sockets and clean the library.
This is all pretty self explanatory.
Server;
Client;
And thats all I got to show you today. Hopefully this helped out some of you, and hopefully explained alot to people who are lost in their C++ networking search.
Here is the complete "Server" program right here;
And here is the client program
Hope you liked it!
----------------------
Winsock 2 C++ Tutorial
----------------------
Winsockets are what computers use to connect two applications over the internet. Today I will be showing you how to make a simple "Server" and "Client" application.
Before we get started, I will assume you have/know the following.
1) Basic C++ Experience
2) Basic Computer terminology
3) Basic Networking Terminology
2) I use Dev-C++, so I assume you do to!
~Linking the Library~
Before you even start diving into the coding, you must link the appropriate library to use Winsock, or your going to get a load of linking errors.
To do this, you simply create a new console application, name it whatever you want (I use client or server)
WARNING:
What I do right now only applys to Dev-C++, if you try it with VC++ or any other IDE, your going to get lost.
Once you have your new project created, goto "project" menu.
Now goto project options.
Goto the parameters tab.
Click "Add Library or Object".
Now locate your Dev-Cpp folder (probably in the C:/ drive)
Now locate the "lib" folder.
Now scroll down until you find the library called "libws2_32.a". Double click on it.
Now press okay.
============================
~Getting the Server Started~
============================
Now that you have linked the correct library, lets get the right headers in.
Code:
#include <iostream>
#include <winsock2.h> //calls the winsocket version 2 header fileHopefully thats self-explanatory.
Now lets startup the winsocket. For this we use the following lines of code;
Code:
WSADATA wsaData; //a required parameter for WSAStartup();
int starterr = WSAStartup(MAKEWORD(2,2), &wsaData); // requests Winsocket version 2.2
if (starterr != 0) {
cout << "Error: " << WSAGetLastError() << " occurred!" << endl;
system ("pause >nul");
WSACleanup();
return 0;}
cout << "WSAStartup Success!" << endl;'WSAGetLastError()' does exactly what it says. It returns the error number that occured. If you do encounter an error, look up the error code on MSDN (MicroSoft Directors Network)
If everything works just right, you get the cheery message, "WSAStartup Successful!".
Now that you started the Winsock we need to create a socket. This can be by the following code;
Code:
SOCKET mysock = socket(AF_INET, SOCK_STREAM, 0); //this line creates the socket
if (mysock == INVALID_SOCKET) { // if anything goes wrong...
cout << "Error: " << WSAGetLastError() << " occurred!" << endl;
system ("pause >nul");
WSACleanup();
return 0;}
COUT << "Socket creation successful!" << endl;Lets take a look at the Socket parameters.
SOCKET mysock | Basically makes a socket named 'mysock'.
socket(AF_INET, SOCK_STREAM, 0) | This is divided into 3 parameters.
1) Address Family
2) Connection type
3) Protocol
AF_INET calls for IPv4.
SOCK_STREAM calls for a reliable two-way connection with the server and client(s)
For the 3rd parameter, I just use '0'. You can look up alternatives on MSDN, but I will be just showing the most simplistic way.
Now that we have created our socket, we need to bind it. To do this we use the following code;
Code:
sockaddr_in anews;
anews.sin_port = htons(80);
anews.sin_addr.s_addr = INADDR_ANY;
anews.sin_family = AF_INET;
if (bind(mysock, (sockaddr*)&anews, sizeof(anews)) == SOCKET_ERROR) {
cout << "Error: " << WSAGetLastError() << " occurred!" << endl;
system ("pause >nul");
WSACleanup();
return 0;}
cout << "Bind successful!" << endl;Okay, this is alot at first, but it gets really easy to remember after a few times of practicing.
To start binding it, you declare the "sockaddr_in" structure. The "anews" can be replaced with anything, as long as its not a reserved word.
You need to specify 3 things inside the structure.
1) Port
2) Connections to accept
3) Address Family
For the port we use "htons(80)". htons converts the number into network byte order. Basically it makes things easy.
INADDR_ANY will accept any connection being made to this socket. You can specify any connection, but for this example, we will be letting anyone in.
AF_INET specifys that we will be using the IPv4 address family. You can specify to use IPv6, but the entire code will need alot of changes in structure. (Well, maybe not, I haven't really looked into it, but I would assume big changes would be needed)
Now that we have binded our socket, its time to listen for connections.
Code:
if (listen(mysock, SOMAXCONN) == SOCKET_ERROR) {
cout << "Error: " << WSAGetLastError() << " occurred!" << endl;
system ("pause >nul");
WSACleanup();
return 0;}
cout << "Socket is now listening for connections..." << endl;Listen has only 2 parameters;
1) Socket
2) Max connections to be accepted
mysock is what I named my socket earlier, so I have to use that.
SOMAXCONN will make the socket accept its maximum connections possible before quitting.
Now that we are listening for connections, we need to accept the connections. To accept connections we must make another socket.
To do this we use the following lines of code;
Code:
SOCKET client; // name it whatever you want, just make sure you make the right changes
client = accept(mysock,NULL,NULL);
if (client == INVALID_SOCKET) {
cout << "Error: " << WSAGetLastError() << " occurred!" << endl;
system ("pause >nul");
WSACleanup();
return 0;}Accept needs 3 parameters. For this tutorial, you only need to worry about one. You just need to specify your socket. For the other two, just set them as 'NULL'.
The next two requirements for the complete server is Send() & Recv(). We will go into that after we make the client.
~Getting the Client started~
You would start out the client the same as you would the server.
Code:
#include <iostream>
#include <winsock2.h>
using namespace std;
int main () {
WSADATA wsaData;
int starterr = WSAStartup(MAKEWORD(2,2), &wsaData);
if (starterr != 0) {
cout << "Error: " << WSAGetLastError() << " occurred!" << endl;
system ("pause >nul");
WSACleanup();
return 0;}
cout << "WSAStartup Successful!" << endl;
SOCKET mysock = socket(AF_INET,SOCK_STREAM,0);
if (mysock == INVALID_SOCKET) {
cout << "Error: " << WSAGetLastError() << " occurred!" << endl;
system ("pause >nul");
WSACleanup();
return 0;}
cout << "Socket Creation Successful!" << endl;Make sure you make the client in an entirely seperate Project and be sure to link the libws2_32.a library.
Now this is where the familiarity ends. You need to connect to a socket, rather than bind to one.
To do this you use the same structure, sockaddr_in.
Code:
sockaddr_in anews;
anews.sin_port = htons(80);
anews.sin_addr.s_adrr = inet_addr("127.0.0.1");
anews.sin_family = AF_INET;
if (connect(mysock,(sockaddr*)&anews, sizeof(anews)) == SOCKET_ERROR) {
cout << "Error: " << WSAGetLastError() << " occurred!" << endl;
system ("pause >nul");
WSACleanup();
return 0;}
cout << "Socket has connected successfuly!" << endl;TO LARGE TO FIT IN ONE POST....SEE BELOW!
Not alot of changes really.
We specify to connect to our localhost here, (inet_addr("127.0.0.1")).
Now when putting the client on a different computer, you specify your IPv4. To get your IPv4 address, you open up your cmd, and type in "ipconfig /all" then it will tell you, just look for it.
=-=-=-=
WARNING:
If you put in your IPv4 address, make sure you port forward. I will not explian how to do that in this tutorial, just google and/or youtube it.
=-=-=-=
Now that we are connected we can finally concentrate on receiving and sending information between the two.
Lets switch our focus back to the Server application.
To send info across the internet, we must put the info into buffers.
Code:
char bufs[200] = "Hello\n";
send(mysock, buf, sizeof(buf), 0);Now to receive is about the samething...
Code:
char bufs[200];
recv(mysock, buf, sizeof(buf), 0);They both have the same parameters as well;
1) Socket
2) Buffer
3) Buffer length
4) Flags (Lets just use zero and keep it simple)
Now after you send you data, and have no more to send, we need to close the sockets and clean the library.
This is all pretty self explanatory.
Server;
Code:
closesocket(mysock);
closesocket(client);
WSACleanup();
return 0;}Client;
Code:
closesocket(mysock);
WSACleanup();
return 0;}And thats all I got to show you today. Hopefully this helped out some of you, and hopefully explained alot to people who are lost in their C++ networking search.
Here is the complete "Server" program right here;
Code:
#include <iostream>
#include <winsock2.h>
using namespace std;
int main(int argc, char *argv[])
{
WSADATA wsaData;
int starterr = WSAStartup(MAKEWORD(2,2), &wsaData);
if (starterr != 0) {
cout << "WSADATA Failed to startup!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;}
cout << "WSADATA Startup Successful!" << endl;
SOCKET mysock = socket(AF_INET, SOCK_STREAM, 0);
if (mysock == INVALID_SOCKET) {
cout << "Socket Creation Failed!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;}
cout << "Socket Creation Successful!" << endl;
sockaddr_in sin;
sin.sin_port = htons(80);
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_family = AF_INET;
if (bind(mysock,(sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR){
cout << "Socket failed to bind!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;}
cout << "Socket Binded Successfuly!" << endl;
while (listen(mysock, SOMAXCONN) == SOCKET_ERROR);
SOCKET client;
int lin = sizeof(sin);
client = accept(mysock,(sockaddr*) &sin, &lin);
cout << "Connection Established!" << endl;
char buf[200] = "Hello\n";
send(client, buf, sizeof(buf), 0);
closesocket(mysock);
closesocket(client);
WSACleanup();
system("pause >nul");
return 0;
}And here is the client program
Code:
#include <iostream>
#include <winsock2.h>
using namespace std;
int main(int argc, char *argv[])
{
WSADATA wsaData;
int starterr = WSAStartup(MAKEWORD(2,2), &wsaData);
if (starterr != 0) {
cout << "WSADATA startup has failed!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;}
cout << "WSADATA Startup Successful!" << endl;
SOCKET mysock = socket(AF_INET, SOCK_STREAM, 0);
if (mysock == INVALID_SOCKET) {
cout << "Socket Creation Failed!" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
WSACleanup();
return 0;}
cout << "Socket Creation Successful!" << endl;
sockaddr_in sin;
sin.sin_port = htons(80);
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_family = AF_INET;
if (connect(mysock,(sockaddr*)&sin, sizeof(sin)) == INVALID_SOCKET) {
cout << "Socket Connection Failed" << endl;
cout << "Error Code: " << WSAGetLastError() << endl;
system("pause >nul");
closesocket(mysock);
WSACleanup();
return 0;}
cout << "Socket Has Connected Successfuly!" << endl;
char buf[200];
recv(mysock, buf, sizeof(buf), 0);
cout << buf;
system("pause >nul");
WSACleanup();
closesocket(mysock);
return 0;
}Hope you liked it!