socket網絡編程基礎
時(shi)間:2018-07-30 來源:未知
網絡編程
socket類型:
流式套(tao)接字(SOCK_STREAM):提供了(le)一個面向(xiang)連接,可靠(kao)地數(shu)(shu)據(ju)(ju)傳輸(shu)服務,數(shu)(shu)據(ju)(ju)無(wu)差錯,無(wu)重復的發送切按發送順序接收。內置流量控(kong)制(zhi),避免數(shu)(shu)據(ju)(ju)流淹(yan)沒慢(man)的接收方。數(shu)(shu)據(ju)(ju)被看做字節流,無(wu)長度限制(zhi)。
數據報套接字(SOCK_DGRAM):提供(gong)無連(lian)接服務。數據包以獨(du)立(li)數據包的形(xing)式(shi)發送(song),不提供(gong)無差錯保證,數據可能(neng)丟(diu)失或重復(fu),順(shun)序發送(song),可能(neng)亂序接收(shou)。
原始套(tao)接(jie)(jie)字(zi)(SOCK_RAM):可以(yi)對較低層次協(xie)議,如IP、ICMP直接(jie)(jie)訪(fang)問(wen)
TCP和(he)UDP協議(yi)對比:TCP面向連接,UDP面向無連接;TCP需要系統提供的(de)資源更多(duo);TCP以流模式發送數(shu)據(ju),UDP以數(shu)據(ju)報(bao)的(de)方式發送數(shu)據(ju);TCP保證數(shu)據(ju)的(de)正確性和(he)順序,UDP不保證。
MSN/QQ使用(yong)的傳(chuan)輸層(ceng)協(xie)議是:登錄TCP 、聊天文件(jian)傳(chuan)輸UDP
TCP(傳(chuan)輸(shu)控制協議(yi)):是一種面向連接的傳(chuan)輸(shu)層(ceng)協議(yi),他能(neng)提供可靠性通信(數(shu)(shu)據(ju)無(wu)誤,數(shu)(shu)據(ju)無(wu)丟失,數(shu)(shu)據(ju)無(wu)失序,數(shu)(shu)據(ju)無(wu)重復到(dao)達的通信)
三次握手:
第一次握手:建立連接時,客(ke)戶端發送syn包(syn=j)到服(fu)務器,并進入SYN_SENT狀態,等(deng)待服(fu)務器確(que)認;SYN:同(tong)步序列編(bian)號(Synchronize Sequence Numbers)。
第(di)二次握手:服(fu)務器收到syn包,必須確(que)認客戶的SYN(ack=j+1),同(tong)時自己(ji)也發送一個(ge)SYN包(syn=k),即SYN+ACK包,此(ci)時服(fu)務器進入SYN_RECV狀態;
第三次(ci)握(wo)手(shou):客(ke)戶端(duan)收到服務器的SYN+ACK包,向服務器發送(song)確認包ACK(ack=k+1),此(ci)包發送(song)完(wan)畢,客(ke)戶端(duan)和服務器進入(ru)ESTABLISHED(TCP連接成功(gong))狀態,完(wan)成三次(ci)握(wo)手(shou)。
四(si)次揮手:(1) TCP客戶端發送一個FIN,用來關閉客戶到服務器的數據傳送。
(2)服務器收(shou)到(dao)這個(ge)FIN,它發(fa)回一(yi)(yi)個(ge)ACK,確認(ren)序號為收(shou)到(dao)的(de)序號加1。和(he)SYN一(yi)(yi)樣,一(yi)(yi)個(ge)FIN將占(zhan)用一(yi)(yi)個(ge)序號。
(3)服(fu)務器關閉客戶端的連接(jie),發送一個FIN給(gei)客戶端。
(4)客(ke)戶端發回(hui)ACK報文確(que)認(ren)(ren),并將確(que)認(ren)(ren)序(xu)(xu)號設(she)置為收到(dao)序(xu)(xu)號加1。
TCP適用(yong)情況:傳(chuan)輸質量要求高,以及(ji)傳(chuan)輸數據(ju)量大的(de)(de)通信;需要可(ke)靠的(de)(de)數據(ju)傳(chuan)輸的(de)(de)時候。
UDP:用戶數據報協(xie)議(yi),是不可靠(kao)的(de)無連(lian)接的(de)協(xie)議(yi)。在數據發送前不需要進行連(lian)接,相對來說效(xiao)率更高(gao)。
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地址裝(zhuang)換為32位的無符號數;
網絡編程接口socket:在(zai)OSI模型(xing)中,位于(yu)會話層和傳輸(shu)層之間。socket()用來建立(li)一個新的(de)socket, 也就(jiu)是向(xiang)系統(tong)注冊, 通知系統(tong)建立(li)一通信端口。參(can)數domain 指(zhi)定使用何種的(de)地址類型(xing), 完整的(de)定義在(zai)/usr/include/bits/socket.h 內, 底下是常見的(de)協議(yi):
PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX 進程通信協議
PF_INET?AF_INET Ipv4網絡協議
PF_INET6/AF_INET6 Ipv6 網絡協(xie)議
PF_IPX/AF_IPX IPX-Novell協議
PF_NETLINK/AF_NETLINK 核心用戶接(jie)口裝置
PF_X25/AF_X25 ITU-T X.25/ISO-8208 協議
PF_AX25/AF_AX25 業余無線AX.25協議
PF_ATMPVC/AF_ATMPVC 存取(qu)原始ATM PVCs
PF_APPLETALK/AF_APPLETALK appletalk(DDP)協議
PF_PACKET/AF_PACKET 初級(ji)封(feng)包接口(kou)
TCP端口號(hao)和(he)UDP端口號(hao)獨立。
HBO(主機(ji)字節(jie)序):小(xiao)端序:底序字節(jie)存(cun)儲在低(di)地址;大端序:高序字節(jie)存(cun)儲在高地址。
網絡(luo)中(zhong)傳輸的字節(jie)(jie)序必須按照(zhao)網絡(luo)字節(jie)(jie)序,即(ji)大端字節(jie)(jie)序;
int socket(int domain, int type, int protocol);
功能:創建通信的文件描(miao)述符;
domain:作用(yong)范圍;
AF_UNIX, AF_LOCAL Local communication unix(7)
AF_INET IPv4 Internet protocols ip(7)
AF_INET6 IPv6 Internet protocols ipv6(7)
type:套(tao)接(jie)字(zi)類型;
SOCK_STREAM 流式套(tao)接字(zi)(TCP);
SOCK_DGRAM 數據(ju)報(bao)套接字(UDP);
SOCK_RAW 原始套接(jie)字:不會(hui)經(jing)過(guo)傳輸層(ceng),直接(jie)從應用層(ceng)到網(wang)絡(luo)層(ceng)
protocol:協(xie)議(yi)的類型(默認使用0);
返(fan)(fan)回(hui)(hui)值(zhi):成功返(fan)(fan)回(hui)(hui)套接(jie)字文件描(miao)述符,失(shi)敗返(fan)(fan)回(hui)(hui)-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);
功能:
設(she)置服務器的IP地址和端口號;
參數:
sockfd:要(yao)設置的套接字(zi)文件描述符;
addr:服務器的IP地(di)址(zhi)和端(duan)口號:
通用(yong)地址(zhi)結構(gou);
struct sockaddr {
sa_family_t sa_family; //協議族(zu)
char sa_data[14]; //ip地址+端口號;
}
專用的地(di)址結(jie)構:(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:地(di)址(zhi)空間的大小;
int listen(int sockfd, int backlog);
功能:
啟動監聽;
參數:
sockfd: 所(suo)要啟動的套(tao)接字;
backlog:所要創建的(de)(de)通信隊列的(de)(de)大小;
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
功(gong)能(neng):設置套接(jie)字屬性;
參數:
sockfd:所要設置(zhi)的套接(jie)字(zi);
level:指定控制套接字的(de)層(ceng)次(通(tong)用套接字、tcp、ip)
optname:具體選項()
optval:存儲套接字的屬(shu)性,
optlen:屬性所占空間(jian)大(da)小;
返回(hui)值:成功(gong)返回(hui)0, 失(shi)敗(bai)返回(hui)-1;

