Skip to content

Instantly share code, notes, and snippets.

@SangSama
Created April 21, 2020 15:57
Show Gist options
  • Save SangSama/4dbf9dd0fd326ce102678144f0600519 to your computer and use it in GitHub Desktop.
Save SangSama/4dbf9dd0fd326ce102678144f0600519 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <WS2tcpip.h>
#include <winSock2.h>
#include <string>
#pragma comment(lib, "ws2_32")
#pragma warning(disable:4996)
DWORD WINAPI ClientThread(LPVOID);
void RemoveClient(SOCKET);
char* ids[64];
SOCKET clients[64];
int numClients = 0;
CRITICAL_SECTION cs;
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 ket noi...\n");
SOCKET client = accept(listener, NULL, NULL);
printf("Ket noi moi: %d\n", client);
CreateThread(0, 0, ClientThread, &client, 0,0);
}
DeleteCriticalSection(&cs);
}
DWORD WINAPI ClientThread(LPVOID lpParam) {
SOCKET client = *(SOCKET*)lpParam;
char buf[256];
int ret;
char cmd[16], id[32], tmp[32];
const char* helloMsg = "Dang nhap theo cu phap \"CONNECT] [your_id]\".\n";
send(client, helloMsg, strlen(helloMsg), 0);
BOOL isRegistered = FALSE;
while (1) {
// nhan du lieu dau vao
ret = recv(client, buf, sizeof(buf), 0);
if (ret <= 0) {
closesocket(client);
return 0;
}
buf[ret] = 0;
printf("Received: %s\n", buf);
if (!isRegistered) { // chua login
//kiem tra cu phap
ret = sscanf(buf, "%s %s %s", cmd, id, tmp);
if (strcmp(cmd, "CONNECT") == 0) {
if (ret == 2) {
int i;
for (i = 0; i < numClients; i++) {
if (strcmp(id, ids[i]) == 0) {
break;
}
}
// kiem tra co trung ID hay khong
if (i < numClients) {
const char* errorMsg = "CONNECT ERROR: ID da duoc su dung. Hay chon ID khac.\n";
send(client, errorMsg, strlen(errorMsg), 0);
}
else {
const char* okMsg = "CONNECT OK.\n";
send(client, okMsg, strlen(okMsg), 0);
isRegistered = TRUE;
EnterCriticalSection(&cs);
ids[numClients] = id;
clients[numClients] = client;
numClients++;
LeaveCriticalSection(&cs);
// thong bao cho cac User khac co nguoi dang nhap
char noticeUserLogin[64];
sprintf(noticeUserLogin, "%s: %s %s", "CONNECT ", id, " - Co User dang nhap\n");
for (int i = 0; i < numClients; i++)
{
if (client != clients[i]) {
send(clients[i], noticeUserLogin, sizeof(noticeUserLogin), 0);
}
}
}
}else{
const char* errorMsg = "CONNECT ERROR Sai cu phap lenh CONNECT.\n";
send(client, errorMsg, strlen(errorMsg), 0);
}
}
else {
const char* errorMsg = "ERROR Lenh khong hop le.\n";
send(client, errorMsg, strlen(errorMsg), 0);
}
}
else { // Da login
char sendBuf[32];
ret = sscanf(buf, "%s", cmd);
// Gui tin nhan
if (strcmp(cmd, "SEND") == 0) {
char target[32];
ret = sscanf(buf + strlen(cmd) + 1, "%s", target);// Doc ALL hay ID
const char* errorMsg = "ERROR error_message - Gui tin nhan that bai.\n";
const char* okMsg = "OK - Gui tin nhan thanh cong.\n";
if (ret == -1) {
const char* errorMsg = "SEND ERROR Sai cu phap lenh SEND.\n";
send(client, errorMsg, strlen(errorMsg), 0);
}
else {
// Send ALL
if (strcmp(target, "ALL") == 0) {
sprintf(sendBuf, "MESSAGE_ALL %s %s", id, buf + strlen(cmd) + 1);
for (int i = 0; i < numClients; i++)
if (clients[i] != client) {
send(clients[i], sendBuf, strlen(sendBuf), 0);
send(client, okMsg, strlen(okMsg), 0);
}
}
else {
sprintf(sendBuf, "MESSAGE %s %s", id, buf + strlen(cmd) + 1);
int check = 0; // kiem tra xem co gui duoc tin nhan khong
for (int i = 0; i < numClients; i++)
if (strcmp(ids[i], cmd + 1) == 0) {
send(clients[i], sendBuf, strlen(sendBuf), 0);
send(client, okMsg, strlen(okMsg), 0);
check = 1;
}
if (check == 0) {
send(client, errorMsg, strlen(errorMsg), 0);
}
}
}
}
// list user are connecting
if (strcmp(cmd, "LIST") == 0) {
char listUser[256] = "List Client: ";
for (int i = 0; i < numClients; i++)
if (clients[i] != client) {
strcat(listUser, ids[i]);
strcat(listUser, " ");
}
send(client, listUser, strlen(listUser), 0);
}
// Logout
if (strcmp(cmd, "EXIT") == 0) {
char noticeUserLogout[64];
sprintf(noticeUserLogout, "%s: %s %s", "DISCONNECT ", id, " - Co User dang xuat\n");
const char* okMsg = "OK - Dang xuat thanh cong.\n";
isRegistered = FALSE;
send(client, okMsg, strlen(okMsg), 0);
RemoveClient(client);
for (int i = 0; i < numClients; i++)
send(client, noticeUserLogout, strlen(noticeUserLogout), 0);
}
}
}
RemoveClient(client);
closesocket(client);
}
void RemoveClient(SOCKET client)
{
int i = 0;
for (; i < numClients; i++)
if (clients[i] == client) break;
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