7

現在、クライアントからのリクエストを受信する UDP サーバーで作業しています。私が受け取ったデータグラムは、5 要素の長さのバイト (char) 配列で、最後の 2 つの要素はポート番号です。

最終的に、このサーバーは独自のデータグラムで IP アドレスとポート番号の両方を返す必要があります。

inet_ntop と、接続して受信した sockaddr 構造体を使用して IP を出力する方法は既に知っていますが、必要な形式ではない文字列を返します。例えば:

string1 = inet_ntop(their_addr.ss_family,get_in_addr(
    (struct sockaddr *)&their_addr),s, sizeof s);

戻り値:

127.0.0.1

また:

[1][2][7][.][0][.][0][.][1]

次のようなものが必要な場合:

[127][0][0][1]

4 要素のバイト配列を作成するために、ある種の文字および配列操作を使用する必要がありますか? または、sockaddr は、この情報をこの 16 進形式のままにして返すことができる方法で持っていますか?

4

3 に答える 3

13

IPv4を想定しています。

sockaddr_storageまたは構造体のアドレスを取得sockaddrしてIPv4バージョンにキャストしたsockaddr_in後、IPv4アドレスの個々のバイトにアクセスできます。

struct sockaddr_in *sin = (struct sockaddr_in *)&their_addr;

次に、IPアドレスの4バイト(ネットワークバイト順)を保持s_addrする32ビット値()であるメンバーのアドレスを取得し、それをへのポインターにキャストして、値の個々のバイトにアクセスできるようにします。 。in_addr_tunsigned char

unsigned char *ip = (unsigned char *)&sin->sin_addr.s_addr;

printf("%d %d %d %d\n", ip[0], ip[1], ip[2], ip[3]);
于 2012-10-10T04:25:20.830 に答える
1

これは、質問で述べたのと同じ目的で使用した単純な不変クラスです。

class address_t {

private:
    uint16_t m_Port = 0;
    std::string m_Ip = "";

public:
    address_t(const sockaddr_in & address) {
        m_Ip = inet_ntoa(address.sin_addr);
        m_Port = ntohs(address.sin_port);
    }

    uint16_t GetPort() const { return m_Port; }
    std::string GetIp() const { return m_Ip; }
    std::string ToString() const {
        return "IP: " + m_Ip + ", Port: " + std::to_string(m_Port);
    }
};
于 2019-04-29T06:56:21.417 に答える