I want to run server and clients using socket programming remotely (clients from my pc and server on a remote host). I have written a program in C++ that runs on local machine, both the client and the server. Now how can I run the server from a different machine? Here in server.cpp I have used INADDR_ANY, I don't have any idea how to give IP address of my PC(on which server is running) to the clients and the ip adddress of the pc (on which I have my client program) to the server. And does client and server have the same port number or they can have a different port number as well? If yes, then how can I assign that?
server.cpp
#include <iostream>
#include <WS2tcpip.h>
#include <string>
#include <cstdlib>
#pragma comment (lib, "ws2_32.lib")
using namespace std;
void main()
{
WSADATA data;
WORD ver = MAKEWORD(2, 2);
int wres = WSAStartup(ver, &data);
if (wres != 0)
{
cerr << "unable to initialize winsock" << endl;
return;
}
SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
if (listening == INVALID_SOCKET)
{
cerr << "unable to create a socket" << endl;
return;
}
sockaddr_in sdata;
sdata.sin_family = AF_INET;
sdata.sin_port = htons(54000);
sdata.sin_addr.S_un.S_addr = INADDR_ANY;
bind(listening, (sockaddr*)&sdata, sizeof(sdata));
listen(listening, SOMAXCONN);
sockaddr_in client;
int csize = sizeof(client);
SOCKET clientsock = accept(listening, (sockaddr*)&client, &csize);
char host[NI_MAXHOST];
char service[NI_MAXSERV];
ZeroMemory(host, NI_MAXHOST);
ZeroMemory(service, NI_MAXSERV);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
cout << host << " connected on port " << service << endl;
}
else
{
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " <<
ntohs(client.sin_port) << endl;
}
//listening
closesocket(listening);
char buf[4096];
//char temp[] = "Hello";
//char *input = temp;
string input;
int inputsize;
while (true)
{
ZeroMemory(buf, 4096);
int recbyte = recv(clientsock, buf, 4096, 0);
if (recbyte == SOCKET_ERROR)
{
cerr << "Error in recv(). Quitting" << endl;
break;
}
if (recbyte == 0)
{
cout << "Client disconnected " << endl;
break;
}
cout << "Client>";
cout << string(buf, 0, recbyte) << endl;
cout << "> ";
getline(cin, input);
send(clientsock, input.c_str(), input.size() + 1, 0);
}
closesocket(clientsock);
WSACleanup();
system("pause");
}
client.cpp
#include <iostream>
#include <string>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
void main()
{
string ipAddress = "127.0.0.1";
int port = 54000;
WSAData data;
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(ver, &data);
if (wsResult != 0)
{
cerr << "Can't start Winsock, Err #" << wsResult << endl;
return;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
cerr << "Can't create socket, Err #" << WSAGetLastError() << endl;
WSACleanup();
return;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR)
{
cerr << "Can't connect to server, Err #" << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
return;
}
char buf[4096];
string userInput;
do
{
cout << "> ";
getline(cin, userInput);
if (userInput.size() > 0)
{
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult != SOCKET_ERROR)
{
ZeroMemory(buf, 4096);
int bytesReceived = recv(sock, buf, 4096, 0);
if (bytesReceived > 0)
{
cout << "SERVER> " << string(buf, 0, bytesReceived) << endl;
}
}
}
} while (userInput.size() > 0);
closesocket(sock);
WSACleanup();
}
I think you do not fully understand the client-server roles. The server does not, cannot and should not know the address of the client connecting to it (although it can know it AFTER the connection). To accomplish the connection, the clients need to know the IP and PORT to which they should connect, and the server should bind its server port (on which it listens) to the correct IP and PORT. The default IP is usually depicted using the INADDR_ANY, and on most cases this is OK, but if you have more than one address on the machine you may have to specify another address. The clients usually do not bind their connecting sockets as their own port numbers is not important. Also their own IP is not important as it is not used during the connection. So what you should do is run your server application on your PC, and give your PC's address and the PORT number to all clients seeking to connect to you.