Last active
April 24, 2020 08:41
-
-
Save lehaiquantb/4d32fef4d081b7bb799b7566f438f1b3 to your computer and use it in GitHub Desktop.
Chatserver model using socket mutilthread
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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