如何实现没有陷阱的简单请求-响应技术
How to implement simple request-reponse techique without pitfalls
我想创建一个简单的客户端和服务器,它们应该按照这样的请求-响应原则工作:
- 客户端发送以下字符串:"do_some_stuff"
- 服务器执行相应的操作并发送以下字符串作为响应:"success"
- 客户端读取响应并做一些记录
- 一段时间后,客户端发送新的命令,所有动作再次重复
听起来容易吗?不幸的是,我有以下问题:
- 我应该使用哪种技术来读取响应?我应该读取数据,直到一些特定的字符序列发生,或者我应该只是调用
read
函数在某种while true
循环,等待连接关闭(我要关闭套接字在服务器端响应发送后)? - 我不明白为什么有这么多的例子只是读取一些字节(例如,1024),并希望答案将被完全读取?如果我们说我们应该获得1024字节,为什么库决定在"成功"之后没有进一步的字节?因为服务器端连接关闭?
- 如果
read_until
将永远无法获得终止字符序列(例如,因为互联网连接)怎么办?它会无限期地等待吗?
#include <boost/asio.hpp>
#include <iostream>
int main()
{
try
{
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(boost::asio::ip::tcp::v4(), "127.0.0.1", "5013");
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ip::tcp::socket s(io_service);
boost::asio::connect(s, iterator);
boost::asio::streambuf request;
std::ostream request_stream(&request);
request_stream << "do_some_stuffn";
boost::asio::write(s, request);
boost::asio::streambuf b;
boost::asio::read_until(s, b, 'n');
std::istream is(&b);
std::string line;
std::getline(is, line);
std::cout << "Reply is: " << line << std::endl;
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "n";
}
}
服务器import socket
import threading
def main():
listener = socket.socket()
listener.bind(('127.0.0.1', 5013))
listener.listen(5)
while True:
client, _ = listener.accept()
worker_thread = threading.Thread(target=worker, args=(client,))
worker_thread.setDaemon(True)
worker_thread.start()
def worker(client):
data = ""
while True:
packet = client.recv(1024)
if not packet:
break
data += packet
if 'n' in data:
line, data = data.split('n', 1)
print line
client.sendall('successn')
if __name__ == '__main__':
main()
这个解决方案有什么问题吗?顺便说一下,为什么client.recv(1024)
在这里完成之前从套接字接收1024字节?它怎么知道后面没有数据呢?它到底是如何工作的?
-
最常用的方法是使用指定长度和读取的头直到接收到所有字节。使用消息分隔符也是用得很多。等待连接结束可以在无连接的情况下完成沟通意味着建立联系,发送信息
-
使用一次读取来获取tcp消息的所有字节是常见的这个错误通常只适用于短消息。这个错误TCP是一个流协议,而不是消息协议。然而,tcp主要用于传递消息。长度参数应该是缓冲区的大小,而不是期望的数字的字节数。读者知道什么时候可以返回,因为发送者发送的数据包。
-
当连接丢失而没有机会通知时(例如power关闭(电缆断开),这会导致无尽的等待。一个可能的解决方案是tcp_keepalive。
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中用vector填充一个简单的动态数组
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的简单if-else语句是如何无法访问的代码
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 如何在boost beast http请求中设置http头
- 发送一个带有libcurl C++问题的帖子请求:s
- 一种在C++中读取TXT配置文件的简单方法
- 在多个核心中处理一个HTTP请求
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 显示错误输出的简单数组排序程序
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 退出简单while循环时出现问题
- 为什么简单的算术减法在"if"条件下不起作用?
- 请求最简单的 OpenMP 目标 GPU 示例
- 从简单的 POST 请求中解析异常
- 为什么这个简单的服务器在非常低的并发请求上失败
- 如何实现没有陷阱的简单请求-响应技术
- 用c++编写的简单HTTP请求