Created
May 1, 2020 08:29
-
-
Save lehaiquantb/ddcacdfdc4e40ceca0aeeecfd9b6e159 to your computer and use it in GitHub Desktop.
ChatServer and TelnetServer using WSAsyncSelect
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
#include <stdio.h> | |
#define _WINSOCK_DEPRECATED_NO_WARNINGS | |
#include <winsock2.h> | |
#include<iostream> | |
#include<string> | |
#include<map> | |
#define WM_SOCKET WM_USER + 1 | |
using namespace std; | |
#pragma comment(lib, "ws2_32") | |
const char* ask = "Enter name ex: \"client_id: xxxxxxxx\":\n"; | |
int num_clients = 0; | |
map<int, string > ids;//cặp ánh xạ một mã client -> id client | |
bool check[64];//check[i] = true nếu client[i] nhập đúng cú pháp | |
SOCKET clients[64]; | |
char buf[256]; | |
//Hàm kiểm tra client có nhập đúng cú pháp | |
string validate(string syntax) { | |
if (!syntax.substr(0, 11).compare("client_id: ")) { | |
return syntax.substr(11); | |
} | |
else return ""; | |
} | |
void removeClient(SOCKET client) { | |
int i = 0; | |
for (; i < num_clients; i++) | |
if (clients[i] == client) break; | |
if (i < num_clients - 1) | |
{ | |
clients[i] = clients[num_clients - 1]; | |
} | |
num_clients--; | |
} | |
BOOL CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM); | |
int main() | |
{ | |
WSADATA wsa; | |
WSAStartup(MAKEWORD(2, 2), &wsa); | |
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); | |
WNDCLASS wndclass; | |
const CHAR* providerClass = "AsyncSelect"; | |
HWND window; | |
wndclass.style = 0; | |
wndclass.lpfnWndProc = (WNDPROC)WinProc; | |
wndclass.cbClsExtra = 0; | |
wndclass.cbWndExtra = 0; | |
wndclass.hInstance = NULL; | |
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); | |
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); | |
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); | |
wndclass.lpszMenuName = NULL; | |
wndclass.lpszClassName = (LPCWSTR)providerClass; | |
if (RegisterClass(&wndclass) == 0) | |
return NULL; | |
// Create a window | |
if ((window = CreateWindow((LPCWSTR)providerClass, L"", WS_OVERLAPPEDWINDOW, | |
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, | |
NULL, NULL, NULL, NULL)) == NULL) | |
return NULL; | |
WSAAsyncSelect(listener, window, WM_SOCKET, FD_ACCEPT); | |
MSG msg; | |
while (GetMessage(&msg, NULL, 0, 0) > 0) | |
{ | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
} | |
BOOL CALLBACK WinProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) | |
{ | |
if (wMsg == WM_SOCKET) | |
{ | |
if (WSAGETSELECTERROR(lParam)) | |
{ | |
closesocket(wParam); | |
return TRUE; | |
} | |
if (WSAGETSELECTEVENT(lParam) == FD_ACCEPT) | |
{ | |
SOCKET client = accept(wParam, NULL, NULL); | |
printf("New client accepted: %d\n", client); | |
WSAAsyncSelect(client, hWnd, WM_SOCKET, FD_READ | FD_CLOSE); | |
send(client, ask, strlen(ask), 0);//Hỏi tên client | |
} | |
if (WSAGETSELECTEVENT(lParam) == FD_READ) | |
{ | |
char buf[256]; | |
int ret = recv(wParam, buf, sizeof(buf), 0); | |
buf[ret - 1] = 0;// Bỏ kí tự xuống dòng và thêm kí tự ngắt xâu | |
//cout << "received: " << buf << endl; | |
if (!check[num_clients])//Kiểm tra nếu client chưa được nhập đúng vào server | |
{ | |
if (validate(buf) == "")//Kiểm tra nếu nhập sai cú pháp | |
{ | |
send(wParam, ask, strlen(ask), 0);//Hỏi lại client | |
} | |
else | |
{ | |
clients[num_clients] = wParam; | |
num_clients++; | |
ids.insert(pair<int, string>((int)wParam, validate(buf))); | |
check[num_clients] = true; | |
} | |
} | |
else//Nếu client đã được đăng nhập đúng thì dữ tin nhắn được sau đó được gửi cho các client còn lại | |
{ | |
for (int j = 0; j < num_clients; j++) | |
{ | |
if (wParam != clients[j]) | |
{ | |
string msg = ids.at((int)wParam) + ":" + buf; | |
send(clients[j], msg.c_str(), msg.size(), 0);//hàm gửi tin nhắn | |
} | |
} | |
} | |
} | |
if (WSAGETSELECTEVENT(lParam) == FD_CLOSE) | |
{ | |
removeClient(wParam); | |
closesocket(wParam); | |
} | |
} | |
} |
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
#include <stdio.h> | |
#define _WINSOCK_DEPRECATED_NO_WARNINGS | |
#include <winsock2.h> | |
#include<iostream> | |
#include<string> | |
#include<map> | |
#include<fstream> | |
#define WM_SOCKET WM_USER + 1 | |
using namespace std; | |
#pragma comment(lib, "ws2_32") | |
const char* askName = "Enter username:\n"; | |
const char* askPass = "Enter password:\n"; | |
int num_clients = 0; | |
bool check[64]; // = true khi client duoc dang nhap dung user, pass | |
bool checkUser = true; // trạng thái đăng nhập, true là đang nhập User, ngược lại là nhập password | |
string user_tmp;//lưu trữ username tạm thời | |
SOCKET clients[64]; | |
char buf[256];//dữ liệu nhận được | |
map<string, string> user_pass; | |
int read_file() { | |
fstream f_user_pass; | |
f_user_pass.open("c:\\temp\\userpass.txt"); | |
char user[100]; | |
char pass[100]; | |
if (!f_user_pass.fail())//nếu đọc lỗi thì dừng | |
{ | |
while (!f_user_pass.eof())//cuối file | |
{ | |
if (f_user_pass >> user && f_user_pass >> pass) { | |
user_pass.insert(pair<string, string>(user, pass)); | |
} | |
else return -1; | |
} | |
} | |
f_user_pass.close(); | |
} | |
void removeClient(SOCKET client) { | |
int i = 0; | |
for (; i < num_clients; i++) | |
if (clients[i] == client) break; | |
if (i < num_clients - 1) | |
{ | |
clients[i] = clients[num_clients - 1]; | |
} | |
num_clients--; | |
} | |
BOOL CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM); | |
int main() | |
{ | |
WSADATA wsa; | |
WSAStartup(MAKEWORD(2, 2), &wsa); | |
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); | |
WNDCLASS wndclass; | |
const CHAR* providerClass = "AsyncSelect"; | |
HWND window; | |
wndclass.style = 0; | |
wndclass.lpfnWndProc = (WNDPROC)WinProc; | |
wndclass.cbClsExtra = 0; | |
wndclass.cbWndExtra = 0; | |
wndclass.hInstance = NULL; | |
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); | |
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); | |
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); | |
wndclass.lpszMenuName = NULL; | |
wndclass.lpszClassName = (LPCWSTR)providerClass; | |
if (RegisterClass(&wndclass) == 0) | |
return NULL; | |
// Create a window | |
if ((window = CreateWindow((LPCWSTR)providerClass, L"", WS_OVERLAPPEDWINDOW, | |
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, | |
NULL, NULL, NULL, NULL)) == NULL) | |
return NULL; | |
WSAAsyncSelect(listener, window, WM_SOCKET, FD_ACCEPT); | |
MSG msg; | |
while (GetMessage(&msg, NULL, 0, 0) > 0) | |
{ | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
} | |
BOOL CALLBACK WinProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) | |
{ | |
if (wMsg == WM_SOCKET) | |
{ | |
if (WSAGETSELECTERROR(lParam)) | |
{ | |
closesocket(wParam); | |
return TRUE; | |
} | |
if (WSAGETSELECTEVENT(lParam) == FD_ACCEPT) | |
{ | |
SOCKET client = accept(wParam, NULL, NULL); | |
printf("New client accepted: %d\n", client); | |
WSAAsyncSelect(client, hWnd, WM_SOCKET, FD_READ | FD_CLOSE); | |
//Hỏi username của client | |
send(client, askName, strlen(askName), 0); | |
} | |
if (WSAGETSELECTEVENT(lParam) == FD_READ) | |
{ | |
char buf[256]; | |
int ret = recv(wParam, buf, sizeof(buf), 0); | |
buf[ret - 1] = 0; // Bỏ kí tự xuống dòng và thêm kí tự ngắt xâu | |
//buf[ret] = 0; | |
if (!check[num_clients])//nếu client chưa đc đăng nhập | |
{ | |
if (user_pass.find(buf) != user_pass.end() && checkUser == true)//nhập username | |
{ | |
send(wParam, askPass, strlen(askPass), 0);//hỏi client Password | |
user_tmp = buf; | |
checkUser = false; | |
} | |
else if (checkUser == false)//nhập password | |
{ | |
if (!user_pass.at(user_tmp).compare(buf))//nếu mật khẩu tương ứng với user là đúng | |
{ | |
check[num_clients] = true; | |
clients[num_clients] = wParam; | |
num_clients++; | |
checkUser = true; | |
} | |
else | |
{ | |
send(wParam, "Wrong password!", 15, 0); | |
send(wParam, askPass, strlen(askPass), 0); | |
} | |
} | |
else {//chưa đúng user name | |
send(wParam, "Wrong username!", 15, 0); | |
send(wParam, askName, strlen(askName), 0); | |
} | |
} | |
else//thực hiện yêu cầu của client đã đăng nhập | |
{ | |
string buff(buf); | |
buff = buff + " > c:\\temp\\out.txt"; | |
system(buff.c_str()); | |
} | |
} | |
if (WSAGETSELECTEVENT(lParam) == FD_CLOSE) | |
{ | |
removeClient(wParam); | |
closesocket(wParam); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment