Last active
April 17, 2020 08:56
-
-
Save lehaiquantb/51e7d31159de058df51817a1e985948c to your computer and use it in GitHub Desktop.
Tuan 33 - Using select to create chatserver, telnetserver
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
// tuan32b1_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<map> | |
using namespace std; | |
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]; | |
#pragma comment(lib, "ws2_32") | |
//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--; | |
} | |
} | |
int main() | |
{ | |
string a = "client_id: xxxxxxxx"; | |
//cout<<validate(a); | |
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); | |
fd_set fdread; | |
int ret; | |
// Chap nhan ket noi va truyen nhan du | |
while (1) { | |
cout << "Waiting for new client..." << endl; | |
FD_ZERO(&fdread); | |
FD_SET(listener, &fdread); | |
for (int i = 0; i < num_clients; i++) | |
{ | |
FD_SET(clients[i], &fdread); | |
} | |
ret = select(0, &fdread, 0, 0, 0); | |
if (ret < 0) | |
break; | |
if (FD_ISSET(listener, &fdread)) | |
{ | |
SOCKET client = accept(listener, NULL, NULL); | |
cout << "Client accepted: " << client << endl; | |
clients[num_clients] = client; | |
send(client, ask, strlen(ask), 0);//Hỏi tên client | |
num_clients++; | |
} | |
for (int i = 0; i < num_clients; i++) | |
{ | |
if (FD_ISSET(clients[i], &fdread)) | |
{ | |
ret = recv(clients[i], buf, sizeof(buf), 0); | |
if (ret <= 0) { | |
removeClient(clients[i]); | |
closesocket(clients[i]); | |
i -= 1; | |
continue; | |
} | |
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(clients[i], ask, strlen(ask), 0);//Hỏi lại client | |
} | |
else | |
{ | |
ids.insert(pair<int, string>((int)clients[i], 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 (clients[i] != clients[j]) | |
{ | |
string msg = ids.at((int)clients[i]) + ":" + buf; | |
send(clients[j], msg.c_str(), msg.size(), 0);//hàm gửi tin nhắn | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
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
// tuan32b2_telnetserver.cpp : This file contains the 'main' function. Program execution begins and ends there. | |
// | |
#include <stdio.h> | |
#include <winsock2.h> | |
#include <iostream> | |
#include<string> | |
#include<fstream> | |
#include<map> | |
using namespace std; | |
const char* askName = "Enter username:\n"; | |
const char* askPass = "Enter password:\n"; | |
int num_clients = 0; | |
#pragma comment(lib, "ws2_32") | |
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--; | |
} | |
} | |
int main() | |
{ | |
read_file(); | |
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); | |
fd_set fdread; | |
int ret; | |
// Chap nhan ket noi va truyen nhan du | |
while (1) { | |
cout << "Waiting for new client..." << endl; | |
FD_ZERO(&fdread); | |
FD_SET(listener, &fdread); | |
for (int i = 0; i < num_clients; i++) | |
{ | |
FD_SET(clients[i], &fdread); | |
} | |
ret = select(0, &fdread, 0, 0, 0); | |
if (ret < 0) | |
break; | |
if (FD_ISSET(listener, &fdread)) | |
{ | |
SOCKET client = accept(listener, NULL, NULL); | |
cout << "Client accepted: " << client << endl; | |
clients[num_clients] = client; | |
//Hỏi username của client | |
send(client, askName, strlen(askName), 0); | |
num_clients++; | |
} | |
for (int i = 0; i < num_clients; i++) | |
{ | |
if (FD_ISSET(clients[i], &fdread)) | |
{ | |
ret = recv(clients[i], buf, sizeof(buf), 0); | |
if (ret <= 0) { | |
//Xóa client khi nó ko còn kết nối tới server | |
removeClient(clients[i]); | |
closesocket(clients[i]); | |
break; | |
} | |
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(clients[i], 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; | |
checkUser = true; | |
} | |
else | |
{ | |
send(clients[i], "Wrong password!", 15, 0); | |
send(clients[i], askPass, strlen(askPass), 0); | |
} | |
} | |
else {//chưa đúng user name | |
send(clients[i], "Wrong username!", 15, 0); | |
send(clients[i], 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()); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment