今天撰寫了一個聊天器,服務端掛到了騰訊云上可以跑了。
但是運行客戶端的時候發現一個小問題。客戶端第一遍運行的沒有問題,可是關閉后,再打開會連不上服務端。
特別迷~~~~
然后打開資源監控器,發現了與客戶端關聯的句柄竟有4個explore.exe,而且PID相同。感覺問題是出在這里,但對這一方面不太了解,所以想請教一下各位大神hh
客戶端exe 如以下地址
http://pan.baidu.com/s/1mh52wIW
代碼如下 用的是靜態編譯
#include <cstdlib>
#include <deque>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/chat_message.hpp>
using boost::asio::ip::tcp;
using namespace std;
typedef std::deque<chat_message> chat_message_queue;
class chat_client
{
public:
//鏈接
chat_client(boost::asio::io_service& io_service,
tcp::resolver::iterator endpoint_iterator)
: io_service_(io_service),
socket_(io_service)
{
tcp::endpoint endpoint = *endpoint_iterator;
socket_.async_connect(endpoint,
boost::bind(&chat_client::handle_connect, this,
boost::asio::placeholders::error, ++endpoint_iterator));
}
void write(const chat_message& msg) // 5
{
io_service_.post(boost::bind(&chat_client::do_write, this, msg));
}
void close()
{
io_service_.post(boost::bind(&chat_client::do_close, this));
}
private:
void handle_connect(const boost::system::error_code& error, // 2
tcp::resolver::iterator endpoint_iterator)
{
if (!error)
{
//鏈接成功,系結。
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.data(), chat_message::header_length), //讀取頭部。
boost::bind(&chat_client::handle_read_header, this, // 3
boost::asio::placeholders::error));
}
else if (endpoint_iterator != tcp::resolver::iterator())
{
//失敗,重新鏈接
socket_.close();
tcp::endpoint endpoint = *endpoint_iterator;
socket_.async_connect(endpoint,
boost::bind(&chat_client::handle_connect, this, // 2
boost::asio::placeholders::error, ++endpoint_iterator));
}
}
void handle_read_header(const boost::system::error_code& error) // 3
{
if (!error && read_msg_.decode_header())
{
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.body(), read_msg_.body_length()), //讀取正文。
boost::bind(&chat_client::handle_read_body, this, // 4
boost::asio::placeholders::error));
}
else
{
do_close();
}
}
void handle_read_body(const boost::system::error_code& error) // 4
{
if (!error)
{
std::cout.write(read_msg_.body(), read_msg_.body_length()); // 輸出正文內容
std::cout << "\n";
boost::asio::async_read(socket_,
boost::asio::buffer(read_msg_.data(), chat_message::header_length),
boost::bind(&chat_client::handle_read_header, this,
boost::asio::placeholders::error));
}
else
{
do_close();
}
}
void do_write(chat_message msg) // 6
{
bool write_in_progress = !write_msgs_.empty();
write_msgs_.push_back(msg);
if (!write_in_progress)
{
boost::asio::async_write(socket_,
boost::asio::buffer(write_msgs_.front().data(),
write_msgs_.front().length()), // 把發言內容寫入buffer
boost::bind(&chat_client::handle_write, this,
boost::asio::placeholders::error));
}
}
void handle_write(const boost::system::error_code& error) // 7
{
if (!error)
{
write_msgs_.pop_front();
if (!write_msgs_.empty())
{
boost::asio::async_write(socket_,
boost::asio::buffer(write_msgs_.front().data(),//判斷是否還有多余的內容
write_msgs_.front().length()),
boost::bind(&chat_client::handle_write, this,
boost::asio::placeholders::error));
}
}
else
{
do_close();
}
}
void do_close()
{
socket_.close();
}
private:
boost::asio::io_service& io_service_;
tcp::socket socket_;
chat_message read_msg_; // 存從buffer讀出的資料
chat_message_queue write_msgs_; // 寫入buffer的資料佇列
};
int main(int argc, char* argv[])
{
try
{
//輸入個人ID
std::cout << "請輸入你的姓名:";
char name[chat_message::max_body_length + 1] = { 0 };
std::cin.getline(name, chat_message::max_body_length + 1);
char login[11] = " login OK!", login_msg[513] = { 0 };
strcpy(login_msg, name);
strncat(login_msg, login, strlen(login) + 1);
//連接
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query("115.159.199.161", "23333");
tcp::resolver::iterator iterator = resolver.resolve(query);
chat_client c(io_service, iterator);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
//發送個人資訊
chat_message msg;
msg.body_length(strlen(login_msg));
memcpy(msg.body(), login_msg, msg.body_length());
msg.encode_header();
c.write(msg);
name[strlen(name)] = ':';
//開啟個人聊天。
char line[chat_message::max_body_length + 1];
while (std::cin.getline(line, chat_message::max_body_length + 1))
{
char massage[chat_message::max_body_length + 1] = { 0 };
strcpy(massage, name);
strncat(massage, line, strlen(line) + 1);
chat_message msg;
msg.body_length(strlen(massage));
memcpy(msg.body(), massage, msg.body_length());// line to msg
msg.encode_header();
c.write(msg);
}
c.close();
t.join(); // 執行執行緒
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
[code=hpp]#pragma warning(disable:4996)
#ifndef CHAT_MESSAGE_HPP
#define CHAT_MESSAGE_HPP
#include <cstdio>
#include <cstdlib>
#include <cstring>
class chat_message
{
public:
enum { header_length = 3 };
enum { max_body_length = 512 };
chat_message()
: body_length_(0)
{
}
const char* data() const
{
return data_;
}
char* data()
{
return data_;
}
size_t length() const
{
return header_length + body_length_;
}
const char* body() const
{
return data_ + header_length;
}
char* body()
{
return data_ + header_length;
}
size_t body_length() const
{
return body_length_;
}
void body_length(size_t length)
{
body_length_ = length;
if (body_length_ > max_body_length)
body_length_ = max_body_length;
}
//chat_message.data_分為兩部分,header和body,其中header為頭,他代表著這個正文body字串的長度,如果header過大,將會取消發送。
//解碼得到字串的長度
bool decode_header()
{
using namespace std;
char header[header_length + 1] = "";
strncat(header, data_, header_length);//鏈接字串
body_length_ = atoi(header);//將字串轉化為整形數
if (body_length_ > max_body_length)
{
body_length_ = 0;
return false;
}
return true;
}
//把字串的長度寫到data_里
void encode_header()
{
using namespace std;
char header[header_length + 1] = "";
sprintf(header, "%3d", body_length_);//資料格式化
memcpy(data_, header, header_length);//拷貝
}
private:
char data_[header_length + max_body_length];
size_t body_length_;
};
#endif
[/code]
uj5u.com熱心網友回復:
上面客戶端exe的鏈接給錯了這個才是
http://pan.baidu.com/s/1pK7yi99
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/115564.html
標籤:網絡通信
