Technology used:
i. C++
ii. Microsoft visual Studio 2010
iii. MFC GUI
iv. Winshock2 Socket
v. TCP/UDP
vi. Windows Thread
This project consist of 3 classes.
1. Server.cpp
2. ServerDlg.cpp
3. ServerManager.cpp
Lets start with core portion -- I mean the network level connection portion.
I have used the Winshock2 library for the purpose of network communication.
You can use this library on windows with MVS 2010 by including library --
# include <winsock2.h>
And as it is multi user and have GUI so we need thread. For this I have used Windows thread.
You can use this windows thread just by adding ---
# include <Windows.h>
So, why we are late. Lets start....
ServerManager.cpp -- core network connection class. In that class I have also demonstrate how to fetch the remote client IP address from a socket connection.
void ServerManager::StartListening(int iPort)
{
iCount=0;
printf("\nInitialising Winsock...");StartListening(int iPort) Initiate a socket and Start listening on a particular port for incoming connections.
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return;
}
printf("Initialised.\n");
//Create a socket
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
m_pDialog->ShowServerInfo("Could not create socket");
}
printf("Socket created.\n");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( iPort );
//Bind
if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == SOCKET_ERROR)
{
printf("Bind failed with error code : %d" , WSAGetLastError());
m_pDialog->ShowServerInfo("Bind failed with error code");
exit(EXIT_FAILURE);
}
puts("Bind done");
//Listen to incoming connections
listen(s , 100);
char *message;
puts("Waiting for incoming connections...");
m_pDialog->ShowServerInfo("Waiting for incoming connections...\n");
c = sizeof(struct sockaddr_in);
while( (new_socket = accept(s , (struct sockaddr *)&client, &c)) != INVALID_SOCKET )
{
puts("Connection accepted");
socklen_t len;
struct sockaddr_storage addr;
char ipstr[INET6_ADDRSTRLEN];
int port;
len = sizeof addr;
getpeername(new_socket, (struct sockaddr*)&addr, &len);
// deal with IPv4:
if (addr.ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in *)&addr;
port = ntohs(s->sin_port);
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
}
printf("Peer IP address: %s\n", ipstr);
m_pDialog->ShowServerInfo("Connected Peer IP address: "+string(ipstr)+"\n");
CWinThread *cTh = AfxBeginThread(
DataThreadFunc,
(LPVOID)new_socket);
++iCount;
sArray[iCount] = new_socket;
}
if (new_socket == INVALID_SOCKET)
{
printf("accept failed with error code : %d" , WSAGetLastError());
return;
}
}
This bold letter means it can accept multiple connection( client ). In that function we used a static global variable to count the connection globally and a global static SOCKET array to stored the socket's pointer for future use from thread.
How ?
You can see on that function I have used windows thread. Here I accept the incoming connection and make a thread for every connection.
You can see that with the function --
UINT __cdecl ServerManager::DataThreadFunc(LPVOID pParam)In DataThreadFunc(LPVOID pParam) I have used the winshock send() API to sending the welcome to the client by client socket.
{
SOCKET pYourSocket = reinterpret_cast<SOCKET>(pParam);
char *message;
message = "Welcome to Matrix chat room.\n";
send(pYourSocket , message , strlen(message) , 0);
char server_reply[2000];
int recv_size;
while((recv_size = recv(pYourSocket , server_reply , 2000 , 0)) != SOCKET_ERROR)
{
server_reply[recv_size] = '\0';
for(int i = 1;i<=iCount; i++)
{
if( send(sArray[i] , server_reply, recv_size , 0) < 0)
{
puts("Send failed");
}
}
}
return 0;
}
Here I also have a while loop with recv() API which continue to listening for client messages.
This is a static function which is called for every incoming connection for 1 time.
After receiving a message from a client this thread server now sends this message to every socket it has on its SOCKET array by fetching the socket.
NOTE : Any smart mind can modified this function and can use for p2p message chat.
COMPLETE CODE
Hello Admin. Please send for me code socket this. Because link download dje. Thank
ReplyDeleteMy email: nguyenlinh20687@gmail.com
There it is -- https://github.com/robelsharma/MultiClientChatRoom
DeleteHi Robel, I couldn't find Server.exe, can you send me?
ReplyDeleteHere is the github link for binary --
Deletehttps://github.com/robelsharma