linux網絡編程之SCTP套接字常用接口(linux如何用sctp)
轉載地址: oracle開發幫助文檔:http://docs.oracle.com/cd/E19253-01/819-7052/index.html
SCTP 套接字接口
當?socket()?調用為?IPPROTO_SCTP?創建套接字時,它會調用特定于 SCTP 的套接字創建例程。針對 SCTP 套接字執行的套接字調用會自動調用相應的 SCTP 套接字例程。在一對一套接字中,每個套接字都對應一個 SCTP 關聯。可以通過調用以下函數來創建一對一套接字:
在一對多風格套接字中,每個套接字都處理多個 SCTP 關聯。每個關聯都具有一個名為?sctp_assoc_t?的關聯標識符。可以通過調用以下函數來創建一對多套接字:
sctp_bindx()
sctp_bindx()?函數管理 SCTP 套接字上的地址。如果?sock?參數為 IPv4 套接字,則傳送給?sctp_bindx()?函數的地址必須為 IPv4 地址。如果?sock?參數為 IPv6 套接字,則傳送給?sctp_bindx()?函數的地址可以為 IPv4 或 IPv6 地址。當傳送給?sctp_bindx()?函數的地址為?INADDR_ANY?或?IN6ADDR_ANY?時,此套接字將綁定到所有可用地址。可以使用?bind(3SOCKET)?綁定 SCTP 端點。
*addrs?參數的值是指向包含一個或多個套接字地址的數組的指針。每個地址都包含在其相應的結構中。如果地址為 IPv4 地址,則它們可以包含在?sockaddr_in?結構或?sockaddr_in6?結構中。如果地址為 IPv6 地址,則它們可以包含在?sockaddr_in6?結構中。可以通過地址類型系列區分地址長度。調用方使用?addrcnt?參數指定數組中的地址數。
如果成功,則?sctp_bindx()?函數將返回 0。如果失敗,則?sctp_bindx()?函數將返回 -1,并將?errno?的值設置為相應的錯誤代碼。
如果沒有為每個套接字地址提供同一端口,則?sctp_bindx()?函數將失敗,并將?errno?的值設置為?EINVAL。
通過對以下零個或多個當前定義的標志執行按位 OR 運算,即可形成?flags?參數:
SCTP_BINDX_ADD_ADDR
SCTP_BINDX_REM_ADDR
SCTP_BINDX_ADD_ADDR?指示 SCTP 將給定地址添加到關聯中。SCTP_BINDX_REM_ADDR?指示 SCTP 從關聯中刪除給定地址。這兩個標志相互排斥。如果同時提供這兩個標志,則?sctp_bindx()?將失敗,并將?errno?的值設置為?EINVAL。
調用方無法刪除關聯中的所有地址。sctp_bindx()?函數拒絕此類嘗試的表現為:函數失敗并將?errno?的值設置為?EINVAL。應用程序可以在調用?bind()?函數之后使用?sctp_bindx(SCTP_BINDX_ADD_ADDR),將其他地址與端點關聯。應用程序可以使用?sctp_bindx(SCTP_BINDX_REM_ADDR)?刪除與偵聽套接字關聯的地址。使用?sctp_bindx(SCTP_BINDX_REM_ADDR)?刪除地址之后,接受新關聯將不會重新關聯已刪除的地址。如果端點支持動態地址,則可以使用?SCTP_BINDX_REM_ADDR?或?SCTP_BINDX_ADD_ADDR?向對等方發送消息來更改對等方的地址列表。在已連接的關聯中添加和刪除地址為可選功能。不支持此功能的實現將返回?EOPNOTSUPP。
如果地址族不是?AF_INET?或?AF_INET6,則?sctp_bindx()?函數將失敗并返回?EAFNOSUPPORT。如果?sock?參數中傳遞給?sctp_bindx()?的文件描述符無效,則?sctp_bindx()?函數將失敗并返回?EBADF。
sctp_opt_info()
sctp_opt_info()?函數將返回與?sock?參數中所述的套接字關聯的 SCTP 級別選項。如果此套接字為一對多風格 SCTP 套接字,則?id?參數的值是某個特定關聯。對于一對一風格 SCTP 套接字,將忽略?id?參數。opt?參數的值指定要獲取的 SCTP 套接字選項。arg?參數的值是為調用程序而分配的特定于選項的結構緩沖區。*len?參數的值為選項長度。
opt?參數可以采用以下值:
返回用于初始化和綁定重新傳輸超時 (retransmission timeout, RTO) 可調參數的協議參數。這些協議參數使用以下結構:
struct sctp_rtoinfo { sctp_assoc_t srto_assoc_id; uint32_t srto_initial; uint32_t srto_max; uint32_t srto_min; };
調用程序提供此值,它指定所關注的關聯。
此值為初始 RTO 值。
此值為最大 RTO 值。
此值為最小 RTO 值。
返回特定于關聯的參數。這些參數使用以下結構:
struct sctp_assocparams { sctp_assoc_t sasoc_assoc_id; uint16_t sasoc_asocmaxrxt; uint16_t sasoc_number_peer_destinations; uint32_t sasoc_peer_rwnd; uint32_t sasoc_local_rwnd; uint32_t sasoc_cookie_life; };
調用程序提供此值,它指定所關注的關聯。
此值指定關聯的最大重新傳輸計數。
此值指定對等方具有的地址數。
此值指定對等方接收窗口的當前值。
此值指定對等方傳輸到的上一個已報告的接收窗口。
此值指定關聯 cookie 的生命周期。可在發出 cookie 時使用此值。
所有使用時間值的參數均以毫秒為單位。
返回?sendto(3SOCKET)?函數調用在此關聯中使用的缺省參數集。這些參數使用以下結構:
struct sctp_sndrcvinfo { uint16_t sinfo_stream; uint16_t sinfo_ssn; uint16_t sinfo_flags; uint32_t sinfo_ppid; uint32_t sinfo_context; uint32_t sinfo_timetolive; uint32_t sinfo_tsn; uint32_t sinfo_cumtsn; sctp_assoc_t sinfo_assoc_id; };
此值指定?sendmsg()?調用的缺省流。
此值始終為 0。
此值包含?sendmsg()?調用的缺省標志。此標志可以采用以下值:
MSG_UNORDERED
MSG_ADDR_OVER
MSG_ABORT
MSG_EOF
MSG_PR_SCTP
此值為?sendmsg()?調用的缺省有效負荷協議標識符。
此值為?sendmsg()?調用的缺省上下文。
此值指定時間段(以毫秒為單位)。在此時間段過后,如果消息傳輸尚未開始,則消息將過期。值為 0 指示消息尚未過期。如果設置了?MSG_PR_SCTP?標志,當消息傳輸未在?sinfo_timetolive?所指定的時間段內成功完成時,消息將過期。
此值始終為 0。
此值始終為 0。
此值由調用程序填充。它指定所關注的關聯。
返回所指定對等地址的參數。這些參數使用以下結構:
struct sctp_paddrparams { sctp_assoc_t spp_assoc_id; struct sockaddr_storage spp_address; uint32_t spp_hbinterval; uint16_t spp_pathmaxrxt; };
調用程序提供此值,它指定所關注的關聯。
此值指定所關注的對等地址。
此值指定心跳間隔(以毫秒為單位)。
此值指定在認為地址不可訪問之前針對此地址嘗試的最大重新傳輸數。
返回有關關聯的當前狀態信息。這些參數使用以下結構:
struct sctp_status { sctp_assoc_t sstat_assoc_id; int32_t sstat_state; uint32_t sstat_rwnd; uint16_t sstat_unackdata; uint16_t sstat_penddata; uint16_t sstat_instrms; uint16_t sstat_outstrms; uint32_t sstat_fragmentation_point; struct sctp_paddrinfo sstat_primary; };
調用程序提供此值,它指定所關注的關聯。
此值為關聯的當前狀態。關聯可以采用以下狀態:
SCTP 端點沒有任何與其關聯的關聯。一旦?socket()?函數調用打開一個端點或端點關閉,則端點便會處于此狀態。
SCTP 端點在調用?bind()?之后綁定到一個或多個本地地址。
此端點在等待來自任何遠程 SCTP 端點的關聯請求。
此 SCTP 端點已發送 INIT 塊并在等待 INIT-ACK 塊。
此 SCTP 端點已將從其對等方的 INIT-ACK 塊接收的 cookie 回顯到對等方。
此 SCTP 端點可以與其對等方交換數據。
此 SCTP 端點已從其上層接收了 SHUTDOWN 元語。此端點不再從其上層接受數據。
處于 SCTP_SHUTDOWN_PENDING 狀態的 SCTP 端點已向其對等方發送了 SHUTDOWN 塊。僅在確認所有從此端點到其對等方的未完成數據之后,才發送 SHUTDOWN 塊。當此端點的對等方發送 SHUTDOWN ACK 塊時,此端點會發送 SHUTDOWN COMPLETE 塊并認為關聯已關閉。
SCTP 端點已從其對等方接收了 SHUTDOWN 塊。此端點不再從其用戶接受新數據。
處于 SCTP_SHUTDOWN_RECEIVED 狀態的 SCTP 端點已向其對等方發送了 SHUTDOWN ACK 塊。此端點僅在其對等方確認來自此端點的所有未完成數據之后發送 SHUTDOWN ACK 塊。當此端點的對等方發送 SHUTDOWN COMPLETE 塊時,將關閉關聯。
此值為關聯對等方的當前接收窗口。
此值為未確認的 DATA 塊數。
此值為等待接收的 DATA 塊數。
此值為傳入的流數。
此值為外發的流數。
如果消息、SCTP 數據包頭和 IP 數據包頭的組合大小超出?sstat_fragmentation_point?的值,則消息會分段。此值等于包目標地址的路徑最大傳輸單元 (Path Maximum Transmission Unit, P-MTU)。
此值包含有關主要對等地址的信息。此信息使用以下結構:
struct sctp_paddrinfo { sctp_assoc_t spinfo_assoc_id; struct sockaddr_storage spinfo_address; int32_t spinfo_state; uint32_t spinfo_cwnd; uint32_t spinfo_srtt; uint32_t spinfo_rto; uint32_t spinfo_mtu; };
調用程序提供此值,它指定所關注的關聯。
此值為主要對等地址。
此值可以采用?SCTP_ACTIVE?或?SCTP_INACTIVE?兩個值中的任意一個。
此值為對等地址的擁塞窗口。
此值為對等地址的當前平滑往返時間計算結果,以毫秒為單位。
此值為對等地址的當前重新傳輸超時值,以毫秒為單位。
此值為對等地址的 P-MTU。
如果成功,則?sctp_opt_info()?函數將返回 0。如果失敗,則?sctp_opt_info()?函數將返回 -1,并將?errno?的值設置為相應的錯誤代碼。如果?sock?參數中傳遞給?sctp_opt_info()?的文件描述符無效,則?sctp_opt_info()?函數將失敗并返回?EBADF。如果?sock?參數中傳遞給?sctp_opt_info()?函數的文件描述符沒有描述套接字,則?sctp_opt_info()?函數將失敗并返回?ENOTSOCK。如果關聯 ID 對于一對多風格 SCTP 套接字而言無效,則?sctp_opt_info()?函數將失敗,并將?errno?的值設置為?EINVAL。如果輸入緩沖區長度對于指定的選項而言過短,則?sctp_opt_info()?函數將失敗,并將?errno?的值設置為?EINVAL。如果對等地址的地址族不是?AF_INET?或?AF_INET6,則?sctp_opt_info()?函數將失敗,并將?errno?的值設置為?EAFNOSUPPORT。
sctp_recvmsg()
使用?sctp_recvmsg()?函數,可以從?s?參數所指定的 SCTP 端點接收消息。調用程序可以指定以下屬性:
此參數為消息緩沖區的地址。
此參數為消息緩沖區的長度。
此參數為指向包含發送主機地址的地址的指針。
此參數為與?from?參數中的地址關聯的緩沖區的大小。
此參數僅在調用程序啟用?sctp_data_io_events?時處于活動狀態。要啟用?sctp_data_io_events,請使用套接字選項?SCTP_EVENTS?調用?setsockopt()?函數。如果啟用了?sctp_data_io_events,則應用程序將接收每個傳入消息的?sctp_sndrcvinfo?結構的內容。此參數為指向?sctp_sndrcvinfo?結構的指針。此結構將在接收消息時進行填充。
此參數包含所有存在的消息標志。
sctp_recvmsg()?函數將返回其接收的字節數。sctp_recvmsg()?函數將在出現錯誤時返回 -1。
如果在?s?參數中傳遞的文件描述符無效,則?sctp_recvmsg()?函數將失敗,并將?errno?的值設置為?EBADF。如果在?s?參數中傳遞的文件描述符沒有描述套接字,則?sctp_recvmsg()?函數將失敗,并將?errno?的值設置為?ENOTSOCK。如果?msg_flags?參數包括值?MSG_OOB,則?sctp_recvmsg()?函數將失敗,并將?errno?的值設置為?EOPNOTSUPP。如果沒有建立關聯,則?sctp_recvmsg()?函數將失敗,并將?errno的值設置為?ENOTCONN。
sctp_sendmsg()
sctp_sendmsg()?函數在發送來自 SCTP 端點的消息時啟用高級 SCTP 功能。
此值指定發送消息的 SCTP 端點。
此值包含?sctp_sendmsg()?函數所發送的消息。
此值為消息的長度,以字節為單位。
此值為消息的目標地址。
此值為目標地址的長度。
此值為應用程序指定的有效負荷協議標識符。
此值為此消息的目標流。
此值為消息未能成功發送到對等方的情況下消息過期之前可以等待的時間段,以毫秒為單位。
如果在發送消息時出現錯誤,則返回此值。
此值在將邏輯運算 OR 以按位形式應用于以下零個或多個標志位時形成:
設置此標志之后,sctp_sendmsg()?函數將無序傳送消息。
設置此標志之后,sctp_sendmsg()?函數將使用?to?參數中的地址,而不使用關聯的主要目標地址。此標志僅用于一對多風格 SCTP 套接字。
設置此標志之后,指定的關聯將異常中止,同時向其對等方發送 ABORT 信號。此標志僅用于一對多風格 SCTP 套接字。
設置此標志之后,指定的關聯將進入正常關機狀態。此標志僅用于一對多風格 SCTP 套接字。
設置此標志之后,如果消息傳輸未在?timetolive?參數所指定的時間段內成功完成,則消息將過期。
sctp_sendmsg()?函數將返回其發送的字節數。sctp_sendmsg()?函數將在出現錯誤時返回 -1。
如果在?s?參數中傳遞的文件描述符無效,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EBADF。如果在?s?參數中傳遞的文件描述符沒有描述套接字,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?ENOTSOCK。如果?flags?參數包括值?MSG_OOB,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EOPNOTSUPP。如果一對一風格套接字的?flags?參數包括?MSG_ABORT?或?MSG_EOF值,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EOPNOTSUPP。如果沒有建立關聯,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?ENOTCONN。如果套接字關閉,禁止進一步寫入,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EPIPE。如果套接字為非阻止套接字并且傳輸隊列已滿,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EAGAIN。
如果控制消息長度不正確,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EINVAL。如果指定的目標地址不屬于關聯,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EINVAL。如果?stream_no?的值不在關聯所支持的外發流數之內,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EINVAL。如果所指定的目標地址的地址族不是?AF_INET?或?AF_INET6,則?sctp_sendmsg()?函數將失敗,并將?errno?的值設置為?EINVAL。
sctp_send()
sctp_send()?函數可供一對一及一對多風格套接字使用。sctp_send()?函數在發送來自 SCTP 端點的消息時啟用高級 SCTP 功能。
此值指定?socket()?函數所創建的套接字。
此值包含?sctp_send()?函數所發送的消息。
此值為消息的長度,以字節為單位。
此值包含用于發送消息的參數。對于一對多風格套接字,此值可以包含消息所發送到的關聯 ID。
此值與?sendmsg()?函數中的標志參數相同。
sctp_send()?函數將返回其發送的字節數。sctp_send()?函數將在出現錯誤時返回 -1。
如果在?s?參數中傳遞的文件描述符無效,則?sctp_send()?函數將失敗,并將?errno?的值設置為?EBADF。如果在?s?參數中傳遞的文件描述符沒有描述套接字,則?sctp_send()?函數將失敗,并將?errno?的值設置為?ENOTSOCK。如果?sinfo?參數的?sinfo_flags?字段包括值?MSG_OOB,則?sctp_send()?函數將失敗,并將?errno?的值設置為?EOPNOTSUPP。如果一對一風格套接字中?sinfo?參數的?sinfo_flags?字段包括?MSG_ABORT?或?MSG_EOF?值,則?sctp_send()?函數將失敗,并將?errno?值的設置為?EOPNOTSUPP。如果沒有建立關聯,則?sctp_send()?函數將失敗,并將?errno?的值設置為?ENOTCONN。如果套接字關閉,禁止進一步寫入,則?sctp_send()?函數將失敗,并將?errno?的值設置為?EPIPE。如果套接字為非阻止套接字并且傳輸隊列已滿,則?sctp_send()?函數將失敗,并將?errno?的值設置為?EAGAIN。
如果控制消息長度不正確,則?sctp_send()?函數將失敗,并將?errno?的值設置為?EINVAL。如果指定的目標地址不屬于關聯,則?sctp_send()?函數將失敗,并將?errno?的值設置為?EINVAL。如果?stream_no?的值不在關聯所支持的外發流數之內,則?sctp_send()?函數將失敗,并將?errno?的值設置為?EINVAL。如果所指定的目標地址的地址族不是?AF_INET?或?AF_INET6,則?sctp_send()?函數將失敗,并將?errno?的值設置為?EINVAL。
分叉關聯
應用程序可以將一對多風格套接字上已建立的關聯分叉為獨立的套接字和文件描述符。對于具有多個偶發消息發送者或接收者的應用程序,如果這些發送者或接收者需要存在于原始一對多風格套接字之下,則獨立的套接字和文件描述符非常有用。應用程序會將傳輸大量數據通信流量的關聯分叉為獨立的套接字描述符。應用程序使用?sctp_peeloff()?調用將關聯分叉為獨立的套接字。新套接字為一對一風格套接字。sctp_peeloff()?函數的語法如下:
從?socket()?系統調用返回的原始一對多風格套接字描述符
要分叉為獨立的文件描述符的關聯的標識符
如果在?sock?參數中傳遞的套接字描述符不是一對多風格 SCTP 套接字,則?sctp_peeloff()?函數將失敗并返回?EOPTNOTSUPP。如果?id?的值為 0 或者?id?的值大于在?sock?參數中傳遞的套接字描述符的最大關聯數,則?sctp_peeloff()?函數將失敗并返回?EINVAL。如果?sctp_peeloff()函數無法創建新的用戶文件描述符或文件結構,則此函數將失敗并返回?EMFILE。
sctp_getpaddrs()
sctp_getpaddrs()?函數將返回關聯中的所有對等地址。
當?sctp_getpaddrs()?函數成功返回時,**addrs?參數的值將指向每個地址相應類型的動態分配的壓縮?sockaddr?結構數組。調用線程使用?sctp_freepaddrs()?函數釋放內存。**addrs?參數的值不能為?NULL。如果?sock?中給定的套接字描述符用于 IPv4 套接字,則?sctp_getpaddrs()?函數將返回 IPv4 地址。如果?sock?中給定的套接字描述符用于 IPv6 套接字,則?sctp_getpaddrs()?函數將同時返回 IPv4 和 IPv6 地址。對于一對多風格套接字,id?參數指定要查詢的關聯。對于一對一風格套接字,sctp_getpaddrs()?函數將忽略?id?參數。當?sctp_getpaddrs()?函數成功返回時,它將返回關聯中的對等地址數。如果此套接字上沒有關聯,則?sctp_getpaddrs()?函數將返回 0,并且不定義?**addrs?參數的值。如果出現錯誤,則?sctp_getpaddrs()?函數將返回 -1,并且不定義?**addrs?參數的值。
如果?sock?參數中傳遞給?sctp_getpaddrs()?函數的文件描述符無效,則?sctp_getpaddrs()?函數將失敗并返回?EBADF。如果?sock?參數中傳遞給?sctp_getpaddrs()?函數的文件描述符沒有描述套接字,則?sctp_getpaddrs()?函數將失敗并返回?ENOTSOCK。如果?sock?參數中傳遞給?sctp_getpaddrs()?函數的文件描述符描述了未連接的套接字,則?sctp_getpaddrs()?函數將失敗并返回?ENOTCONN。
sctp_freepaddrs()
sctp_freepaddrs()?函數將釋放所有由之前的?sctp_getpaddrs()?調用所分配的資源。sctp_freepaddrs()?函數的語法如下:
*addrs?參數為包含?sctp_getpaddrs()?函數所返回的對等地址的數組。
sctp_getladdrs()
sctp_getladdrs()?函數將返回套接字上的所有本地綁定的地址。sctp_getladdrs()?函數的語法如下:
當?sctp_getladdrs()?函數成功返回時,addrs?的值將指向動態分配的壓縮?sockaddr?結構數組。sockaddr?結構為每個本地地址的相應類型。調用應用程序使用?sctp_freeladdrs()?函數釋放內存。addrs?參數的值不能為 NULL。
如果?sd?參數引用的套接字為 IPv4 套接字,則?sctp_getladdrs()?函數將返回 IPv4 地址。如果?sd?參數引用的套接字為 IPv6 套接字,則?sctp_getladdrs()?函數將同時返回相應的 IPv4 或 IPv6 地址。
針對一對多風格套接字調用?sctp_getladdrs()?函數時,id?參數的值指定要查詢的關聯。sctp_getladdrs()?函數在一對一套接字上運行時將忽略?id?參數。
當?id?參數的值為 0 時,無論為何種特定關聯,sctp_getladdrs()?函數都將返回本地綁定的地址。當?sctp_getladdrs()?函數成功返回時,它將報告綁定到套接字的本地地址數。如果未綁定套接字,則?sctp_getladdrs()?函數將返回 0,并且不定義?*addrs?的值。如果出現錯誤,則?sctp_getladdrs()?函數將返回 -1,并且不定義?*addrs?的值。
sctp_freeladdrs()
sctp_freeladdrs()?函數將釋放所有由之前的?sctp_getladdrs()?調用所分配的資源。sctp_freeladdrs()?函數的語法如下:
*addrs?參數為包含?sctp_getladdrs()?函數所返回的對等地址的數組。
Linux 網絡
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。