Skip to content

Instantly share code, notes, and snippets.

@lehaiquantb
Last active April 17, 2020 08:56
Show Gist options
  • Save lehaiquantb/51e7d31159de058df51817a1e985948c to your computer and use it in GitHub Desktop.
Save lehaiquantb/51e7d31159de058df51817a1e985948c to your computer and use it in GitHub Desktop.
Tuan 33 - Using select to create chatserver, telnetserver
// 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
}
}
}
}
}
}
}
// 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