1
几个星期前我已经开始Windows套接字编程。C++中面向对象的客户端套接字应用程序设计
到目前为止,我已经创建了一个C风格的客户端应用程序(基于IOCP),它与VC++ 2010中的网络硬件设备进行通信。应用程序通过LAN或串行端口与设备(作为服务器)异步通信:
- 创建插座/或处理,以串行端口
- 连接到服务器类型为std
- 生成命令::载体(例如,登录命令)
- 经由套接字或串行端口发送命令
- 接收通过插座或串口 从服务器
现在,我想使我现有的客户端应用程序更加面向对象的,我已经想出了下面的类层次结构
class IClient
{
public:
virtual bool Connect() = 0;
virtual bool Disconnect() = 0;
virtual bool Send() = 0;
virtual bool Receive() = 0;
...
};
class Client : public IClient
{
public:
Client();
virtual ~Client();
virtual bool Connect() = 0;
virtual bool Disconnect() = 0;
virtual bool Send() = 0;
virtual bool Receive() = 0;
...
private:
std::string m_strConnectionSettings; // IP address, port number etc
};
class SerialClient : public Client
{
public:
bool Connect()
{
...
m_hPort = CreateFile(_T("COM3"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
...
}
bool Disconnect()
{
...
CloseHandle(m_hPort);
...
}
bool Send()
{
...
WriteFile(m_hPort, (LPCVOID)(&vecByteData[0]), vecByteData.size(), &dwNumberOfBytesWritten, NULL);
...
}
bool Receive()
{
...
ReadFile(m_hPort, (LPVOID)&vecBuffer[0], vecBuffer.size(), &dwNumberOfBytesRead, NULL);
...
}
...
private:
HANDLE m_hPort; // Handle returned by CreateFile().
DCM m_dcb;
};
class SocketClient : public Client
{
public:
SocketClient();
virtual ~SocketClient();
virtual bool Connect() = 0;
virtual bool Disconnect() = 0;
virtual bool Send() = 0;
virtual bool Receive() = 0;
...
private:
SOCKET m_socket; // Handle returned by WSASocket().
};
class TcpClient : public SocketClient
{
public:
TcpClient();
~TcpClient();
bool Connect()
{
...
WSAConnect(m_sock, (LPSOCKADDR)&server, sizeof(server), NULL, NULL, NULL, NULL);
...
}
bool Disconnect()
{
...
closesocket(m_sock);
...
}
bool Send()
{
...
WSASend(m_sock, ...);
...
}
bool Receive()
{
...
WSARecv(m_sock, ...);
...
}
...
};
class UdpClient : public SocketClient
{
public:
UdpClient();
~UdpClient();
bool Connect();
bool Disconnect();
bool Send();
bool Receive();
...
};
然而,在我的电脑网络上的知识仍然是初步的,所以我觉得很难计算机网络概念转化成C++的设计。例如,在上面的设计中,我不知道“Port”在哪里。如果我有“Port”类和“Socket”类,“Port”类是否包含“Socket”类或相反或无意义?
如果您能就上述设计给我一些反馈,我会很感激。
- 我已经对Boost.Asio做了一个简短的介绍,看看它是如何设计的。
- 对不起,如果我的问题含糊不清。
感谢您的回复。我想在服务器端和客户端更像是“套接字”,例如[link](http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/practical/PracticalSocket.h) 。 “连接”也包含一个套接字对象作为其成员变量?所以,如果你做了像connection.connect(“IP地址”,“端口”),然后在内部创建一个套接字对象并调用WSAConnect()? – jpen
从我的角度来看'socket'是用户(编码器)在服务器端需要了解的东西。在引擎盖下还有一个名为“套接字”的wsa结构,每一端都有一个内部实现细节,您应该隐藏起来 – pm100
因此,如何更改上面的层次结构?顺便说一句,我的设计只关心客户端(我没有任何控制服务器端实现)。我最初的想法是隐藏“TcpClient”和“UdpClient”中的套接字句柄。 – jpen