1

私は数週間前にWindowsソケットプログラミングを始めました。

これまで、VC ++ 2010でネットワーク化されたハードウェアデバイスと通信するCスタイルのクライアントアプリケーション(IOCPベース)を作成しました。このアプリケーションは、LANまたはシリアルポートを介してデバイス(サーバーとして機能)と非同期で通信します。

  • シリアルポートへのソケット/またはハンドルを作成します
  • サーバーに接続する
  • std :: vectorタイプのビルドコマンド(例:ログオンコマンド)
  • ソケットまたはシリアルポートを介してコマンドを送信する
  • ソケットまたはシリアルポートを介して応答を受信する
  • サーバーから切断します

ここで、既存のクライアントアプリケーションをよりオブジェクト指向にしたいので、次のクラス階層を考え出しました(パラメーターは省略されています)。

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を簡単に見て、その設計方法を確認しました。
  • 質問が曖昧な場合は申し訳ありません。
4

1 に答える 1

2

典型的なソケット抽象化モデル

  • ソケット、サーバー側の何か
  • クライアント、サーバー側でモデル化されたもの (1 つのソケットには多くのクライアントがあります)
  • クライアント側でモデル化された接続

通常、ポート番号は、サーバーでは socket.listen メソッドの一部であり、クライアントでは connection.connect メソッドの一部です。

IPアドレスと同じ

于 2012-06-25T21:47:44.580 に答える