網絡編程
socket類型:
流式套接字(SOCK_STREAM):提供了一個面向連接,可靠地數據傳輸服務,數據無差錯,無重復的發送切按發送順序接收。內置流量控制,避免數據流淹沒慢的接收方。數據被看做字節流,無長度限制。
數據報套接字(SOCK_DGRAM):提供無連接服務。數據包以獨立數據包的形式發送,不提供無差錯保證,數據可能丟失或重復,順序發送,可能亂序接收。
原始套接字(SOCK_RAM):可以對較低層次協議,如IP、ICMP直接訪問
TCP和UDP協議對比:TCP面向連接,UDP面向無連接;TCP需要系統提供的資源更多;TCP以流模式發送數據,UDP以數據報的方式發送數據;TCP保證數據的正確性和順序,UDP不保證。
MSN/QQ使用的傳輸層協議是:登錄TCP 、聊天文件傳輸UDP
TCP(傳輸控制協議):是一種面向連接的傳輸層協議,他能提供可靠性通信(數據無誤,數據無丟失,數據無失序,數據無重復到達的通信)
三次握手:
第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,并進入SYN_SENT狀態,等待服務器確認;SYN:同步序列編號(Synchronize Sequence Numbers)。
第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態;
第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態,完成三次握手。
四次揮手:(1) TCP客戶端發送一個FIN,用來關閉客戶到服務器的數據傳送。
(2)服務器收到這個FIN,它發回一個ACK,確認序號為收到的序號加1。和SYN一樣,一個FIN將占用一個序號。
(3)服務器關閉客戶端的連接,發送一個FIN給客戶端。
(4)客戶端發回ACK報文確認,并將確認序號設置為收到序號加1。
TCP適用情況:傳輸質量要求高,以及傳輸數據量大的通信;需要可靠的數據傳輸的時候。
UDP:用戶數據報協議,是不可靠的無連接的協議。在數據發送前不需要進行連接,相對來說效率更高。
int inet_aton(const char *cp, struct in_addr *inp);
typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr;
};
功能: 將點分形式的IP地址裝換為32位的無符號數;
網絡編程接口socket:在OSI模型中,位于會話層和傳輸層之間。socket()用來建立一個新的socket, 也就是向系統注冊, 通知系統建立一通信端口。參數domain 指定使用何種的地址類型, 完整的定義在/usr/include/bits/socket.h 內, 底下是常見的協議:
PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX 進程通信協議
PF_INET?AF_INET Ipv4網絡協議
PF_INET6/AF_INET6 Ipv6 網絡協議
PF_IPX/AF_IPX IPX-Novell協議
PF_NETLINK/AF_NETLINK 核心用戶接口裝置
PF_X25/AF_X25 ITU-T X.25/ISO-8208 協議
PF_AX25/AF_AX25 業余無線AX.25協議
PF_ATMPVC/AF_ATMPVC 存取原始ATM PVCs
PF_APPLETALK/AF_APPLETALK appletalk(DDP)協議
PF_PACKET/AF_PACKET 初級封包接口
TCP端口號和UDP端口號獨立。
HBO(主機字節序):小端序:底序字節存儲在低地址;大端序:高序字節存儲在高地址。
網絡中傳輸的字節序必須按照網絡字節序,即大端字節序;
int socket(int domain, int type, int protocol);
功能:創建通信的文件描述符;
domain:作用范圍;
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
type:套接字類型;
SOCK_STREAM 流式套接字(TCP);
SOCK_DGRAM 數據報套接字(UDP);
SOCK_RAW 原始套接字:不會經過傳輸層,直接從應用層到網絡層
protocol:協議的類型(默認使用0);
返回值:成功返回套接字文件描述符,失敗返回-1;
int accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:
設置服務器的IP地址和端口號;
參數:
sockfd:要設置的套接字文件描述符;
addr:服務器的IP地址和端口號:
通用地址結構;
struct sockaddr {
sa_family_t sa_family; //協議族
char sa_data[14]; //ip地址+端口號;
}
專用的地址結構:(man 7 ip);
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address. */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
addrlen:地址空間的大小;
int listen(int sockfd, int backlog);
功能:
啟動監聽;
參數:
sockfd: 所要啟動的套接字;
backlog:所要創建的通信隊列的大小;
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
功能:設置套接字屬性;
參數:
sockfd:所要設置的套接字;
level:指定控制套接字的層次(通用套接字、tcp、ip)
optname:具體選項()
optval:存儲套接字的屬性,
optlen:屬性所占空間大小;
返回值:成功返回0, 失敗返回-1;