I've made two C++ files, one for a server and then a client. As you can see below in the code, I wanted to display to the client that they have been connected, and their ID as well, but when I try to connect, it clears the console correctly, but doesn't display their ID. I noticed that when I close the server and the client is still running, the client then displays the ID. Not too sure what the problem is, will be awaiting your replies! Thanks in advance, and here's the code.
Server:
// First, we'll include all the required files
#include <winsock.h>
#include <iostream>
#include <Windows.h>
using namespace std;
#pragma comment(lib, "ws2_32.lib") // Require this lib for winsock
SOCKADDR_IN addr; // This structure saves the address and ports of the server
int addrlen = sizeof(addr); // This saves the length of the address
int Counter; // Counts how many connected clients there are
SOCKET sConnect; // Socket for incoming connections
SOCKET sListen; // Socket for listening
SOCKET *Connections; // Socket for all the connections
// Init the winsock library
int InitWinSock()
{
int Val = 0; // Make a default
WSAData wsaData;
WORD DllVersion = MAKEWORD(2, 1);
Val = WSAStartup(DllVersion, &wsaData); // Initialise winsock
return 0;
}
int main()
{
system("color 0a"); // Change the console color to black-green
cout << "Server Started." << endl;
// Winsock Init
int Val = InitWinSock();
if(Val != 0)
{
// If WinSock Init fails, display an error
MessageBoxA(NULL, "Error while starting WinSock!", "Error", MB_OK | MB_ICONERROR);
exit(1); // Stop the procedure
}
Connections = (SOCKET*) calloc(64, sizeof(SOCKET));
// Init the sockets
sListen = socket(AF_INET, SOCK_STREAM, NULL);
sConnect = socket(AF_INET, SOCK_STREAM, NULL);
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // Server address, 127.0.0.1 is localhost
addr.sin_port = htons(2222); // Server port
addr.sin_family = AF_INET; // This is the type of connection
bind(sListen, (SOCKADDR*)&addr, sizeof(addr)); // Bind server to address and port
listen(sListen, 64); // Listen for any incoming connections
while(true)
{
if(sConnect = accept(sListen, (SOCKADDR*)&addr, &addrlen))
{
Connections[Counter] = sConnect;
char *Name = new char[64]; // The name of the client
ZeroMemory(Name, 64); // We make the char empty
sprintf(Name, "%i", Counter);
send(Connections[Counter], Name, 64, NULL); // We send the ID to the client
cout << "New Connection!" << endl;
Counter ++; // Increase the amount of clients
} // end if accept the connection
Sleep(50); // Wait 50 milliseconds
} // end while search for connections
}
Client:
#include <iostream>
#include <winsock.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
SOCKET sConnect; // The connection socket
SOCKADDR_IN addr; // The server adress
int Startup_WinSock()
{
WSADATA wsaData;
WORD DllVersion = MAKEWORD(2, 1);
int Val = WSAStartup(DllVersion, &wsaData);
return Val;
}
int main()
{
system("color 0a");
int Val = Startup_WinSock();
if(Val != 0)
{
cout << "Can't Startup WinSock!" << endl; // Display error
exit(1);
}
sConnect = socket(AF_INET, SOCK_STREAM, NULL);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(2222);
addr.sin_family = AF_INET;
cout << "Please press [ENTER]" << endl;
cin.get();
Val = connect(sConnect, (SOCKADDR*)&addr, sizeof(addr)); // Connect with the server
if(Val != 0)
{
cout << "Can't reach the server!" << endl;
main (); // Try again
}
else
{
system("cls"); // Clear the screen
int ID;
char *nID = new char[64]; // Client's ID
char *hello = new char[64]; // Message from the server
ZeroMemory(nID, 64);
ZeroMemory(hello, 64);
recv(sConnect, nID, 64, NULL); // Receive ID from server
recv(sConnect, hello, 64, NULL); // Receive message from the server
ID = atoi(nID); // Cast to an int
cout << hello << endl;
cout << "Your ID: " << ID << endl;
cin.get();
}
return 0;
}
First, you have no error checking here. You need to add error checking throughout the program or it will be impossible to troubleshoot.
Second, you have no message handling here. What happens if the first
recv
gets 3 bytes? You'll wind up reading the rest of the ID into the hello field.Third, you don't send any messages. So the second
recv
will wait until the read attempt fails, which is when the server is terminated.