2017-07-13 4 views
1

このエラーが発生した後、私はここで答えを探していましたが、ほとんど誰もがこのエラーを修正するのは難しい方法でしたが、まったく起こるので、私はこの質問が正確に重複しているとは思わない。C - getaddrinfoは "Servnameはai_socktypeではサポートされていません"を返します

私はTCPソケットをC言語で書いています。ソケット名をホスト名とするために "getaddrinfo"関数を使いました。私のコードはgithubにあります。

が、ときに私は、私はこのエラーました "のgetaddrinfo" でUDP socketを作成しようとしました:私はとき気づいai_socktype

いるclient.c

const char *host = argv[1]; 
const char *service = argv[2]; 
const char *string = argv[3]; 

struct addrinfo addrCriteria; 
memset(&addrCriteria, 0, sizeof(addrCriteria)); 
addrCriteria.ai_family = AF_UNSPEC; 
addrCriteria.ai_socktype = SOCK_DGRAM; 
addrCriteria.ai_protocol = IPPROTO_UDP; 

struct addrinfo *servAddr; 
int ret = getaddrinfo(host, service, &addrCriteria, &servAddr); 
if(ret != 0) 
    sysError(gai_strerror(ret)); 

のためにサポートされていない
servnameのを私は "service"に8080のような数値入力を与えますが、エラーは返されませんが、ポート名/ 8081を指す "tproxy"のような文字列をサービス名として使用すると、 'gai_strerror'

明らかに、gai_strerrorはこう述べています。「サービス名は 'SOCK_DGRAM'ソケットタイプではサポートされていませんが、なぜですか?私は "getaddrinfo"の正確な理由は、UDPソケットを介してネームサービスをサポートしていないことを意味しますか?
ポート番号ではなくUDPソケットでサービス名を使用する他の方法はありますか?どうやって?

答えて

1

TL; DR:tproxy UDPポートはありません。 tproxyは、UDPサービスではないため


あなたがサービスデータベースでUDPソケット用tproxyサービスを検索する場合は、

getent services tproxy/udp 

あなたは、何も出力を取得していません。あなたはプロトコルに関係なく、getent services | grep -e tproxyのすべてtproxyサービスを見れば、あなたはtproxyサービスのみTCPプロトコルのために定義されていることを意味

tproxy 8081/tcp 

が表示されます。

これは、あなたがサービス8081ためのUDPソケット用getaddrinfo()を求めるならtproxyのみTCPとUDPないために定義されているので、あなたは、何かを見つけることができませんことを意味します。

xmpp-clientサービスのUDPソケットを求める場合と比較してください。少なくとも私のサービスデータベース(getent services xmpp-client/udpは)

xmpp-client   5222/udp jabber-client 

そして実際、getaddrinfo()は喜んで(xmpp-clientまたはjabber-clientサービスなどを使用して)、そのようなUDPソケットのソケット記述を提供して応答します。

したがって、TCPポートとUDPポートの両方が定義されているxmpp-clientのようなサービスがあります。 TCPとUDPはIP上の異なるプロトコルであるため、私のシステムでは、getent services | grep -e xmpp-client

xmpp-client   5222/tcp jabber-client 
xmpp-client   5222/udp jabber-client 

を示し、それがサービスはTCPとUDP通信用に別のポート番号を使用することができることを意味します。したがって、サービスデータベースがTCPとUDPソケットの同じポート番号を返すだけであると仮定することは無理です。

つまり、一部のサービスでサービスデータベースに登録されている名前のTCPポートが使用されているため、その名前を使用してUDPポート番号を指定できる必要があると誤解しているためエラーが発生します。 。

TCPとUDPは別々のプロトコルであり、ポート番号のスペースは別です。たとえば、TCPポート512はUnix exec rサービスで使用されますが、UDPポート512はbiffメール通知サービスで使用されます。

+0

私は '/ etc/services'ファイルとTCPとUDPの異なるサービス名を見逃したとは思えません!これは私の大きな間違いを覚えていました。 TCPとUDPの両方の接続で定義されているように、 'http-alt' servnameで動作します。よろしくお願いします。 –

1

serviceパラメータに数値以外の値を指定した場合、/ etc/servicesファイルでルックアップされます(Linuxの場合)。このファイルは、サービス名をポート/プロトコルにマッピングします。以下にいくつかのサンプルエントリです:「tproxy」のためのあなたの/ etc/servicesファイルにはUDPエントリが存在しないので、

ssh    22/tcp 
telnet   23/tcp 
domain   53/tcp       # name-domain server 
domain   53/udp 

あなたがエラーを取得している理由があります。このファイルを見て、 "domain"などのUDPポートを指定するエントリを探します。 53/tcpと53/udpの両方のエントリが必要です。サービス名として "domain"を渡すと、結果が返されます。

関連する問題