我第一次尝试在TCP/IP上实现一些网络协议。我设计了一个,但我不确定它是否有效。
设计
所以我的想法是:在客户端打开与服务器的TCP/IP连接后,每次它想发出请求时,首先它会发送请求大小,然后是一些分隔符(新行或空格),然后是实际请求(HTTP中使用相同的主体,我认为在大多数情况下都会使用这个想法)。
例如,如果客户端想要发送GET ASD,它实际上会发送7个GET ASD(假设空格是分隔符)。
对于服务器端,对于每个客户端,服务器都有一个缓冲区,用于保存传入的请求。每当它从客户端获得一些新的字符块时,服务器就会将其附加到相应的客户端缓冲区。之后,服务器将尝试获取请求的内容长度(在本例中为7),并检查缓冲区的其余长度是否大于或等于该长度。如果大于或等于,服务器将获取请求的实际内容,进行处理并将其从缓冲区中删除。
实施
这一切都是关于协议设计的,现在是关于实际实现的一些注意事项:我认为这里的主要问题是有效地实现和管理缓冲区。
我认为大小为2*MAX_size_of_ONE_REQUEST的缓冲区将足以服务于一个客户端,因为服务器接收到的块可以同时包含第一个请求的结束和第二个请求的开始。这是我的假设,如果我错了,我们需要更多或更少的空间,请告诉我为什么。
我认为有两种方法可以将请求存储在缓冲区中,直到它们得到服务:
每当服务器接收到新的字符块时,服务器就会将其附加到缓冲区的右侧。一旦缓冲区包含完整的请求,服务器就会处理它,并将缓冲区的所有剩余部分向左移动到缓冲区空间的开头。
一些循环缓冲区,在处理请求后一开始不移动缓冲区。
这是我关于实现异步I/O缓冲区的想法(服务器将使用epoll/kqueue/select来接收来自客户端的请求)。我认为若服务器不使用异步I/O和客户端通信,那个么实现缓冲区就会简单得多。
此外,我还没有决定服务器在接收到格式错误的请求时应该如何操作。是否应该关闭与客户端的连接?
也许我写了很多东西,但我对这个话题很感兴趣,想尽可能多地学习。我想有很多人和我一样,所以任何关于这个话题的现实世界问题以及解决这些问题的最佳实践都会非常有帮助。