Registration Forgot password?
Login
Password
Remember me
Login through VKontakte
General > Articles > Multithreaded chat on socket

Multithreaded chat on C++ Socket

To study the Socket in C++ was developed a simplified analog chat icq. For the implementation of IM used cSocket own class that encapsulate the call API functions for working with sockets

The general principle of the IM creates a separate stream which creates a socket server. This simple socket server listening on port connections to the account from another computer. Basically stream created "eternal" cycle, which handles user input keyboard.You can download sources files

// include headers
// standart studio header, must be firs in any cpp file of project
#include "stdafx.h"
#include 
#include 
#include 
#include 
#include 
#include 
// include class that encapsulate socket API
#include "cSocket.h"

#define InputLength 1024

using namespace std;

int nBindPort = 2155;
int nConnPort = 2155;
bool bClientConnected = false;

// function will working child thread
unsigned __stdcall RunChatSrv(void* Srv) {
 // create server socket
 cSocket* SockSrv = (cSocket*)Srv;
 SockSrv->BindPort(nBindPort, 1);
 std::cout << "Start server thread. Bind port " << 
 nBindPort << std::endl;

 // eternal cycle - waiting client connection
 while(true) {
   int Res = 0;
   // create socket for service client
   cSocket* Client = SockSrv->Accept(Res);
   std::string strRb;
   if (Res == 1) { // if connect successful
     strRb = Client->ReceiveBytes(); // get string from client
     if (!strRb.empty()) {
       Client->SendLine("OK"); // acknowledge client 
       // show received information and client's ip to screen
       std::cout << inet_ntoa(Client->saiSockAddr.sin_addr) <<
       "-> " << strRb << std::endl;
     }
     // free memory that get Client object
     delete Client;
   }
 }
}

// function send message
int sendChatMessage(const char* szIP,const char* szMess, bool bConnect = true) {
 int Res = 0;
 // create client socket
 cSocket* SockCl = new cSocket;
 // connect to received ip and port
 if (SockCl->Connect(szIP, nConnPort)) {
   // відсилаємо повідовлення
   SockCl->SendLine(szMess);
   // try get acknowledge 
   std::string Answ = SockCl->ReceiveBytes();
   if (Answ.find("OK") == 0) {
     Res = 1;
     bClientConnected = true;
     if (bConnect) {
       std::cout << "successfull connect to " << 
       szIP << ":" << nConnPort << std::endl;
     }
   }
 } else {
   bClientConnected = false;
   std::cout << "error when try connect to " << 
   szIP << ":" << nConnPort << std::endl;
 }
 delete SockCl;
 return Res;
}

int getStrLen(const char* cszData) {
	int nLen = 0;
	while(*cszData++) {
	 nLen++;
	}
	return nLen;
}

int main(int argc, char* argv[]) {
	cSocket* SockSrv = new cSocket;
	
	std::cout << "Type Port ty Bindn";
	std::cin >> nBindPort;

	std::cout << "Type Port ty Connectn";
	std::cin >> nConnPort;

	unsigned int nSrvThRes;
  // create thread for server socket
  _beginthreadex(0, 0, RunChatSrv,(void*) SockSrv, 0, &nSrvThRes);

	char szInput[InputLength];
	string strInput;

	std::string strIP = "";

	int nStrLn = 0;
 
 // get command from user
 while(1) {
   cin.getline(szInput, InputLength);
   nStrLn = getStrLen(szInput);
   strInput.assign(szInput, nStrLn);
   if (strInput.empty()) {
    continue;
   }
   if (strInput.find("exit") == 0) {
    break;
   }
   basic_string ::size_type stIdx = strInput.find("conn ");
   if (stIdx != string::npos) {
     strIP = strInput.substr(stIdx + 5);
     sendChatMessage(strIP.c_str(), "try connectn");
   } else {
     if (bClientConnected) {
      sendChatMessage(strIP.c_str(), strInput.c_str(), false);
     } else {
      std::cout << "you must connect first use command "conn 127.0.0.1"" << std::endl;
     }
   }
 }
 
 delete SockSrv;

 return 0;
}

If you have any question please, ask in comment

You can add comment on current page, or on forum page there.Post count 7.

Last comment

10.03.2015
Юрий спасибо за ответ, постоянно забывал об этом ws2_32.lib
08.12.2014
Res[ulResLn] = '\0';
cszBuff[nReceiveBytes] = '\0';
08.12.2014
А всё-таки, какая версия Visual Studio (VS 2010 даёт 16 неразрешенных внешних элементов):

мне помогло
1)
#pragma comment(lib, "ws2_32.lib")
или
свойства проекта, свойства конфигурации, компоновщик, ввод, дополнительные зависимости, добавить wsock32.lib
2) если ругается на concat, то
concat(Res, strlen(Res), cszBuff, nReceiveBytes);
меняем на
cszBuff[nReceiveBytes] = '';
strcat_s(Res, ulResLn, cszBuff);
и
concat(Tmp, strlen(Tmp), Res, ulResLn - 1);
меняем на
Res[ulResLn] = '';
strcat_s(Tmp, ulResLn, Res);

Name*E-mail
Code*