目錄
參考書籍:
源碼下載下傳:
建立socket
參考書籍:
《UNIX環境進階程式設計(Advanced Programming int the UNIX Environment Second Edition)》
《TCP/IP詳解 卷1:協定(TCP/IP Illustrated Volume 1 [Stevens 1994])》
《TCP/IP詳解 卷2:實作(TCP/IP Illustrated Volume 2 [Wright and Stevens 1995])》
《TCP/IP詳解 卷3:T/TCP、HTTP、NNTP及UNIX域協定(TCP/IP Illustrated Volume 3 [Stevens 1996])》
《UNIX網絡程式設計 卷1:套接字聯網API(UNIX Network Programming Volume 1: The Sockets Networking API)》
《UNIX網絡程式設計 卷2:程序間通信(UNIX Network Programming Volume 2: Interprocess Communications)》
源碼下載下傳:
UNIX Network Programming, Volume 1, Third Edition Source Code
建立socket
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
參數解析:
- domain:套接字通信域;
- type:套接字類型;
- protocol:通常為0,表示按照給定域和類型選擇的預設協定。
- AF_INET + SOCK_STREAN = TCP(傳輸控制協定);
- AF_INET + SOCK_DGRAM = UDP(使用者資料報協定)。
套接字通信域:
域 | 描述 |
AF_INET | IPv4 |
AF_INET6 | IPv6 |
AF_UNIX | UNIX域,在UNIX系統中也稱 AF_LOCAL |
AF_UNSPEC | 未指定 |
套接字類型:
類型 | 描述 | 備注 |
SOCK_DGRAM | 長度固定的,無連接配接不可靠的封包傳遞 | 資料報是一種自包含協定,與對方通信時不需要邏輯連接配接,填好位址後直接發送。 |
SOCK_RAM | IP協定的資料報接口(POSIX.1中為可選) | |
SOCK_SEQPACKET | 長度固定,有序,可靠的面向連接配接的封包傳遞 | |
SOCK_STREAN | 有序、可靠、雙向的面向連接配接的封包傳遞 | 應用程式意識不到封包界限,因為是位元組流,可能是多次函數調用才拿到所有封包。 |
套接字是雙向的,允許通過函數shutdowm來禁止套接字上的輸入和輸出。
#include <sys/socket.h>
int shutdown(int sockfd, int how);
參數解析:
- sockfd:socket函數傳回的檔案描述符;
- how:禁用開關:
- SHUT_RD:關閉讀
- SHUT_WR:關閉寫;
- SHUT_RDWR:關閉讀寫。
位元組序轉換:
大端位元組序(big-endian),小端位元組序(little-endian)。
TCP/IP協定采用大端位元組序,以下是位元組序轉換函數:
#include <arpa/inet.h>//老系統在<netinet/in.h>中
uint32_t htonl(uint32_t hostint32); //主機轉網絡,傳回以網絡位元組序表示的32位整型數
uint32_t htons(uint32_t hostint16); //主機轉網絡,傳回以網絡位元組序表示的16位整型數
uint32_t ntohl(uint32_t netint32); //網絡轉主機,傳回以主機位元組序表示的32位整型數
uint32_t ntohs(uint32_t netint16); //網絡轉主機,傳回以主機位元組序表示的16位整型數
Linux中,對于IPv4的套接字結構體定義:
struct in_addr
{
in_addr_t s_addr; /* IPv4 address */
};
struct sockaddr_in
{
sa_family_t sin_family; /* address family */
in_port_t sin_port; /* port number */
struct in_addr sin_addr; /* IPv4 address */
unsigned char sin_zero[8]; /* filler,預設全部置0 */
};
IPv6的套接字結構體定義:
struct in6_addr
{
uint8_t s6_addr[16];
};
struct sockaddr_in6
{
sa_family_t sin6_family;
in_port_t sin6_port;
uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
uint32_t sin6_scope_id;
};