-
Notifications
You must be signed in to change notification settings - Fork 5
/
ChatClient-SingleUser.cpp
executable file
·128 lines (106 loc) · 3.25 KB
/
ChatClient-SingleUser.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
///
/// 单用户版Chat客户端
/// 起两个线程,一个线程专门负责读,一个线程专门负责写
///
#include "Codec.h"
#include "./TCP/TcpClient.h"
#include "./TCP/InetAddress.h"
#include "./Base/Timestamp.h"
#include "./Net/EventLoop.h"
#include "./Net/EventLoopThreadPool.h"
#include <cstdio>
#include <functional>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <thread>
#include <chrono>
#include <string>
#include <mutex>
class ChatClient {
public:
ChatClient(EventLoop* loop, const InetAddress& servAddr)
: client_(loop, servAddr),
conn_(client_.connection()),
codec_(
std::bind(&ChatClient::onStringMessage, this, _1, _2, _3)
)
{
client_.setConnectionCallback(
std::bind(&ChatClient::onConnection, this, _1)
);
client_.setMessageCallback(
std::bind(&Codec::onMessage, &codec_, _1, _2, _3)
);
client_.enableRetry();
}
void connect() {
client_.connect();
}
void disconnect() {
client_.disconnect();
}
void sendToServer(const std::string msg) {
{
std::lock_guard<std::mutex> locker(mutex_);
printf("Client send [%s]\n", msg.c_str());
if(conn_) {
codec_.send(conn_, conn_->localAddress().toIpPort()+" "+ msg);
}
}
}
//default dtor is okay
private:
void onConnection(const TcpConnectionPtr& conn) {
printf("%s->%s: connected? %d (0 for Down, 1 for UP)\n",
conn->localAddress().toIpPort().c_str(),
conn->peerAddress().toIpPort().c_str(),
conn->connected());
std::lock_guard<std::mutex> locker(mutex_);
if(conn->connected()) {
conn_ = conn;
}
else {
conn_.reset();
}
}
void onStringMessage(const TcpConnectionPtr& conn, const std::string msg,Timestamp recvTime) {
// 接收到了消息,这个时候要做什么呢,很简单,打印出来就是了
printf("\n");
printf("[%s]\t", recvTime.toFormattedString(false).c_str()); // 消息中没有格式
printf(">>> %s\n", msg.c_str());
//std::cout << msg << "\n" << std::endl;
}
TcpClient client_;
std::mutex mutex_; //保护conn_
TcpConnectionPtr conn_;
Codec codec_;
};
using namespace std::placeholders;
int main(int argc, char** argv) {
if(argc != 3){
printf("Usage: %s <chatServer IP> <Port>\n", argv[0]);
exit(0);
}
EventLoopThread loopThread; //这个进程, 析构函数包含了线程的回收
InetAddress serverAddr(argv[1], atoi(argv[2]));
ChatClient client(loopThread.startLoop(), serverAddr);
client.connect(); //连接服务器--这里有一次runInLoop
std::string line;
//主线程接收键盘输入
while(true){
printf("\n$$: ");
std::getline(std::cin, line);
if(line.size() == 0) {
printf("Empty messge is not allowed!");
continue;
}
client.sendToServer(line);
}
client.disconnect();
// using namespace std::chrono_literals;
// printf("Exitting...\n");
// std::this_thread::sleep_for(2s);
// printf("Exitted!\n");
return 0;
}