Skip to content

Instantly share code, notes, and snippets.

@lehaiquantb
Last active April 24, 2020 08:41
Show Gist options
  • Save lehaiquantb/4d32fef4d081b7bb799b7566f438f1b3 to your computer and use it in GitHub Desktop.
Save lehaiquantb/4d32fef4d081b7bb799b7566f438f1b3 to your computer and use it in GitHub Desktop.
Chatserver model using socket mutilthread
// ChatServer.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <stdio.h>
#include <winsock2.h>
#include <iostream>
#include<string>
#include<vector>
#pragma comment(lib, "ws2_32")
#pragma warning(disable:4996)
using namespace std;
const char* errorSyntax = "SYNTAX ERROR\n";
const char* errorCnt = "[CONNECT] ERROR \- Dang nhap that bai\n";
const char* CntMsg = "[CONNECT] OK \- Dang nhap thanh cong\n";
const char* errorDisconnect = "[DISCONNECT] ERROR \- Dang xuat that bai\n";
const char* disconnectMsg = "Disconnecting...\n";
const char* sendErr = "[SEND] ERROR \- Gui tin nhan that bai\n";
const char* sendOk = "[SEND] OK \- Gui tin nhan thanh cong\n";
const char* helloMsg = "Dang nhap theo cu phap [CONNECT] ID\n";
const char* listOk = "[LIST] OK \- Lay danh sach thanh cong\n";
CRITICAL_SECTION cs;
char* ids[64];
SOCKET clients[64];
int numClients = 0;
vector<string> useridExist{ "user1","user2","user3" };//mảng các tài khoản đã tồn tại
DWORD WINAPI ClientThread(LPVOID);
void removeClient(int);
bool isExistUser(string user) {//hàm kiểm tra xem user có tồn tại chưa?
for (int i = 0; i < useridExist.size(); i++)
if (useridExist[i] == user)
return true;
return false;
}
int main()
{
WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);
InitializeCriticalSection(&cs);
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(9000);
SOCKET listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
bind(listener, (SOCKADDR*)&addr, sizeof(addr));
listen(listener, 5);
while (1)
{
printf("Dang cho cac ket noi...\n");
SOCKET client = accept(listener, NULL, NULL);
printf("Ket noi moi: %d", client);
CreateThread(0, 0, ClientThread, &client, 0, 0);
}
DeleteCriticalSection(&cs);
}
DWORD WINAPI ClientThread(LPVOID lpParam)
{
SOCKET client = *(SOCKET*)lpParam;
int indexOfClient;
char buf[256];
int ret;
char cmd[16], id[32], tmp[32];
char sendBuf[256];
send(client, helloMsg, strlen(helloMsg), 0);
// Thuc hien xac thuc client
while (1)
{
ret = recv(client, buf, sizeof(buf), 0);
if (ret <= 0)
{
closesocket(client);
return 0;
}
buf[ret] = 0;
printf("Received: %s\n", buf);
// Kiem tra cu phap va id da ton tai chua
ret = sscanf(buf, "%s %s %s", cmd, id, tmp);
if (ret == 2)
{
if (strcmp(cmd, "[CONNECT]") == 0 && isExistUser(id) && strcmp(cmd, "ALL") != 0)
{
sprintf(sendBuf, "%s: %s %s", "[USER] CONNECT ", id, "\n");
// Chuyen tiep tin nhan den cac client khac co user dang xuat
for (int i = 0; i < numClients; i++)
send(clients[i], sendBuf, strlen(sendBuf), 0);
send(client, CntMsg, strlen(CntMsg), 0);
EnterCriticalSection(&cs);
ids[numClients] = id;
indexOfClient = numClients;
clients[numClients] = client;
numClients++;
LeaveCriticalSection(&cs);
break;
}
else
send(client, errorCnt, strlen(errorCnt), 0);//connect that bai
}
else
send(client, errorCnt, strlen(errorCnt), 0);//connect that bai
}
// Thuc hien chuyen tiep tin nhan, dang xuat, lay danh sach
while (1)
{
ret = recv(client, buf, sizeof(buf), 0);
if (ret <= 0)
{
removeClient(indexOfClient);
closesocket(client);
return 0;
}
buf[ret] = 0;
printf("Received: %s\n", buf);
ret = sscanf(buf, "%s %s", cmd, tmp);
if (ret == -1 || (strcmp(cmd, "[SEND]") != 0 && strcmp(cmd, "[DISCONNECT]") != 0 && strcmp(cmd, "[LIST]") != 0))
{
send(client, errorSyntax, strlen(errorSyntax), 0);
}
else if (strcmp(cmd, "[SEND]") == 0)
{
if (strcmp(tmp, "ALL") == 0)
{
sprintf(sendBuf, "%s %s: %s", "[MESSAGE_ALL]", id, buf + strlen(cmd) + strlen(tmp) + 1);
// Chuyen tiep tin nhan den cac client khac
for (int i = 0; i < numClients; i++)
if (clients[i] != client) {
send(clients[i], sendBuf, strlen(sendBuf), 0);
if (ret != SOCKET_ERROR)
send(client, sendOk, strlen(sendOk), 0);
else
send(client, sendErr, strlen(sendErr), 0);
}
}
else
{
//Gui tin nhan den user chi dinh
sprintf(sendBuf, "%s %s: %s", "[MESSAGE]", id, buf + strlen(cmd) + strlen(tmp) + 1);
for (int i = 0; i < numClients; i++)
if (strcmp(ids[i], tmp) == 0) {
ret = send(clients[i], sendBuf, strlen(sendBuf), 0);
if (ret != SOCKET_ERROR)
send(client, sendOk, strlen(sendOk), 0);
else
send(client, sendErr, strlen(sendErr), 0);
}
}
}
else if (strcmp(cmd, "[DISCONNECT]") == 0)//Dang xuat
{
send(client, disconnectMsg, strlen(disconnectMsg), 0);//Dang dang xuat
ret = closesocket(client);
if (!ret)
{
removeClient(indexOfClient);
// Chuyen tiep tin nhan den cac client khac co u◘ser dang xuat
sprintf(sendBuf, "%s: %s %s", "[USER] DISCONNECT ", id, "\n");
for (int i = 0; i < numClients; i++)
send(clients[i], sendBuf, strlen(sendBuf), 0);
return 0;
}
else
send(client, errorDisconnect, strlen(errorDisconnect), 0);//Dang xuat that bai
}
else if (strcmp(cmd, "[LIST]") == 0)//Lay danh sach
{
string list = "[LIST] OK - Lay danh sach thanh cong: \n[";
list += ids[0];
for (int i = 1; i < numClients; i++)
{
list = list + "," + ids[i];
}
list += "]\n";
const char* t = list.c_str();
send(client, t, strlen(t), 0);
}
}
}
void removeClient(int i) {//ham xoa client theo chi so i trong mang
if (i < numClients - 1)
{
clients[i] = clients[numClients - 1];
}
numClients--;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment