构建一个简单的TCP服务器

在Windows环境下进行套接字编程时,经常会遇到一些挑战。幸运的是,有一些类库可以帮助简化这个过程。本文将介绍如何使用这些类库来构建一个简单的TCP服务器

TCP服务器的工作原理

TCP服务器通过调用listen函数来监听套接字。当客户端连接到服务器时,accept函数会返回一个新的套接字,服务器可以通过这个新创建的套接字与客户端通信。一个表现良好的服务器可能会继续以某种方式服务原始套接字。如果不是这样,其他尝试连接的客户端将不会得到及时的服务。一种流行的架构(虽然不是唯一的)是使用一个线程来监听主套接字,并分派其他线程来处理与每个客户端的通信。tcpserver类就使用了这种架构。

tcpserver类

以下是tcpserver类声明的开始部分:

class tcpserver : public sock, public thread { public: tcpserver(unsigned int max_conn = 0, DWORD idle_time = INFINITE, const char *name = 0); ~tcpserver(); ... };

这个类继承自sockC++套接字包装器,以及thread,一个封装Windows线程的类。由于它继承自sock,可以使用所有可用的函数来控制这个套接字的行为。特别是,可能需要将它绑定到一个接口和端口号。

示例:构建一个回显服务器

本文附带的代码中包含了一个小型示例,实现了一个回显服务器。这个服务器简单地等待客户端发送的行,并将它们连同新行一起回显。以下是如何构建回显服务器的示例代码:

tcpserver srv; srv.bind(inaddr(INADDR_LOOPBACK, 12321)); srv.start();

要了解客户端连接到主服务器线程监听的端口时发生了什么,需要查看tcpserv实现(在文件tcpserver.cpp中)。每个thread对象,tcpserver是一个线程,都有一个run()函数,它完成了大部分工作。

线程类

这个类是一系列封装基本Windows同步对象的包装器的一部分。知道现在有很多同步对象(包括线程)作为标准C++库的一部分。在写包装器的时候,还没有这些便利的工具。即使在今天,包装器仍然提供了紧密模仿Windows API函数的优势。所有这些类都继承自一个抽象基类syncbase,它封装了一个Windows句柄,无论是线程句柄、事件句柄、信号量、互斥锁等。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485