2016-05-27 7 views
2

私は読んで、Cのアイデアを得ようとしていて、Java chatUDPTCPと数年前にプログラムしようとしましたが、私はそれをやりとりしました。 私はソケットをプログラムしたいと思います。私はたくさんのドキュメントを読んでいますが、常に不明な部分があります。すべてのドキュメントには欠陥があります。 は例えば、私が使用する約1つのc socket()関数の型とプロトコルの違いは何ですか?

int socket(int domain, int type, int protocol); 

ドメインは明らかにAF_INETありさ、と私はTCPソケットをしたい場合、私はタイプがSOCK_STREAMされるべきだと思うが、プロトコルは何ですか?ドキュメンテーションは、それは0でなければならないと言います...なぜ???それは何ですか?

+0

AF_INET、SOCK_STREAM、IPPROTO_SCTPを渡します。 – immibis

答えて

1

特定のソケットタイプをサポートするプロトコルが異なる可能性があります。そのため、をsocket(2)に指定することもできます。

マンページ(強調鉱山)から:

プロトコルは ソケットで使用する特定のプロトコルを指定します。特定のプロトコルファミリ内で特定のソケットタイプの をサポートするプロトコルは通常1つのみです。この場合、 プロトコルは0と指定できます。 しかし、多くのプロトコルが存在する可能性があります。このように指定する。

だから、0などのプロトコルを指定する必須ではありません。実際に0は、標準ライブラリが正しいプロトコルを見つけ出すことを意味します。しかし、それを明示的に指定することができ、そうすることは完全に有効です。

Linuxでは、あなたが行うことで利用可能なプロトコルを見ることができます:

$ cat /etc/protocols 
# Internet (IP) protocols 
# 
# Updated from http://www.iana.org/assignments/protocol-numbers and other 
# sources. 
# New protocols will be added on request if they have been officially 
# assigned by IANA and are not historical. 
# If you need a huge list of used numbers please install the nmap package. 

ip 0 IP  # internet protocol, pseudo protocol number 
hopopt 0 HOPOPT  # IPv6 Hop-by-Hop Option [RFC1883] 
icmp 1 ICMP  # internet control message protocol 
igmp 2 IGMP  # Internet Group Management 
ggp 3 GGP  # gateway-gateway protocol 
ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'') 
st 5 ST  # ST datagram mode 
+0

あなたと矛盾して申し訳ありませんが、/ etc/protocolsの内容は、指定された説明を表すためにこれらのプロトコル番号の一般的な受け入れを示しています。 linuxカーネルで利用可能な実際のプロトコルは、どのようにコンパイルされているかによって異なります。また、ファイルの内容は、カーネルがこれらのすべてをサポートしているとは言えません。さらに、/ etc/protocolsの起源はLinuxシステムにはないが、古代のUNIXでは、内容が正確であるにもかかわらず、これらのファイルは通常、カーネル構築プロセスからではなく、Linuxディストリビューションメーカーから来る。 –

1

ソケットの最後プロトコルパラメータは、()の生のパケットで使用することができます。私はそれを実際に説明しようとします。

Rawソケットを使用してTCPスタックからパケットを取得する場合、このパラメータを使用して送受信するパケットデータの量を制御できます。

socket (AF_INET, SOCK_RAW, IPPROTO_TCP); 

上記の呼び出しは、カーネルがパケットをIPヘッダーまで処理する生のパケットを提供します。パケットを送信するときには、パケットの残りの部分を手動で入力する必要があります。パケットを読むときには、カーネルはTCPヘッダーの内容もデータとともに提供します。一方

socket (AF_INET, SOCK_RAW, IPPROTO_RAW); 

IPPROTO_RAWを使用して、上向きにIP層からのパケットを制御することができます。カーネルはあなたにサービスを提供します。イーサネットヘッダー、残りのパケットはあなたのコントロールにあります。

+0

もっと一般的には、プロトコルスイート 'socket(AF_INET、SOCK_STREAM、0)の中で特定のプロトコルを指定するのに使われます;' TCPはIPプロトコルスイートのデフォルトのストリーミングソケットですので、TCPソケットを与えます。しかし、代わりにSCTPプロトコルを使いたい場合、 'socket(AF_INET、SOCK_STREAM、IPPROTO_SCTP);'を使うことができます。パケットベースのBluetoothソケットが必要な場合は、 'socket(AF_BLUETOOTH、SOCK_SEQPACKET、BTPROTO_L2CAP)'または 'socket(AF_BLUETOOTH、SOCK_SEQPACKET、BTPROTO_RFCOMM)' – nos

3

ソケットのmanページから:

プロトコルは、ソケットで使用する特定のプロトコルを指定します。指定されたプロトコルファミリ内の特定のソケットタイプをサポートするために通常は1つのプロトコルしか存在しません。この場合、プロトコルは0として指定できます。しかし、多くのプロトコルが存在する可能性があります。方法。使用するプロトコル番号は、通信が行われる「通信ドメイン」に固有です。プロトコル(5)を参照してください。プロトコル名文字列をプロトコル番号にマップする方法については、getprotoent(3)を参照してください。プロトコルのmanページによる

このファイルには、TCP/IPサブシステムから利用可能な様々なDARPAインターネットプロトコルを記述し、プレーンなASCIIファイルです。 ARPAのインクルードファイルの番号を使用する代わりに、またはそれを推測するだけで、それを参照する必要があります。これらの番号は、任意のIPヘッダーのプロトコルフィールドで発生します。

各行は次の形式は次のとおりです。

プロトコル番号別名...

...

は/ etc /プロトコルのプロトコル定義ファイル。

そして、私のLinuxボックスの/ etc/protocolsファイル内:

ip  0  IP    # internet protocol, pseudo protocol number 
hopopt 0  HOPOPT   # hop-by-hop options for ipv6 
icmp 1  ICMP   # internet control message protocol 
igmp 2  IGMP   # internet group management protocol 
ggp  3  GGP    # gateway-gateway protocol 
ipencap 4  IP-ENCAP  # IP encapsulated in IP (officially ``IP'') 
st  5  ST    # ST datagram mode 
tcp  6  TCP    # transmission control protocol 
cbt  7  CBT    # CBT, Tony Ballardie <[email protected]> 
egp  8  EGP    # exterior gateway protocol 
igp  9  IGP    # any private interior gateway (Cisco: for IGRP) 
bbn-rcc 10  BBN-RCC-MON  # BBN RCC Monitoring 
... 

そしてgetprotocolのmanページによると:

getprotobyname()関数はprotoent構造体を返しますプロトコル名の名前と一致するデータベースからのエントリ用。必要に応じて、データベースへの接続が開かれます。

次のように...

protoent構造を定義した:

struct protoent { 
    char *p_name;  /* official protocol name */ 
    char **p_aliases; /* alias list */ 
    int p_proto;  /* protocol number */ 
} 

ですから(getprotobynameする "IP" を渡した場合)、それはあなたが数である0を返しますとにかく使っています。しかし、あなたがプロトコルの名前を知らなくても、0を直接使うことは常に安全です。

関連する問題