socket程式設計在TCP中的應用
1.socket基本操作
1.1 socket()函式
int socket(int domain, int type, int protocol);
socket()用於建立一個socket描述符(socket descriptor),它唯一標識一個socket。這個socket描述字跟檔案描述字一樣,後續的操作都有用到它,把它作為引數,通過它來進行一些讀寫操作。
- domain:即協議域,又稱為協議族(family)。常用的協議族有,AF_INET、AF_INET6、AF_LOCAL(或稱AF_UNIX,Unix域socket)、AF_ROUTE等等。協議族決定了socket的地址型別,在通訊中必須採用對應的地址,如AF_INET決定了要用ipv4地址(32位的)與埠號(16位的)的組合、AF_UNIX決定了要用一個絕對路徑名作為地址。
- type:指定socket型別。常用的socket型別有,SOCK_STREAM、SOCK_DGRAM(UDP)、SOCK_RAW、SOCK_PACKET(TCP)、SOCK_SEQPACKET等等
- protocol:故名思意,就是指定協議。常用的協議有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它們分別對應TCP傳輸協議、UDP傳輸協議、STCP傳輸協議、TIPC傳輸協議
socket建立一個socket時,返回的socket描述字它存在於協議族(address family,AF_XXX)空間中,但沒有一個具體的地址。如果想要給它賦值一個地址,就必須呼叫bind()函式,否則就當呼叫connect()、listen()時系統會自動隨機分配一個埠。
1.2 bind()函式
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
bind()函式把一個地址族中的特定地址賦給socket。例如對應AF_INET、AF_INET6就是把一個ipv4或ipv6地址和埠號組合賦給socket。
- sockfd:即socket描述字,它是通過socket()函式建立了,唯一標識一個socket。bind()函式就是將給這個描述字繫結一個名字
- addr:一個const struct sockaddr *指標,指向要繫結給sockfd的協議地址
- addrlen:對應的是地址的長度
通常伺服器在啟動的時候都會繫結一個眾所周知的地址(如ip地址+埠號),用於提供服務,客戶就可以通過它來接連伺服器;而客戶端就不用指定,有系統自動分配一個埠號和自身的ip地址組合。這就是為什麼通常伺服器端在listen之前會呼叫bind(),而客戶端就不會呼叫,而是在connect()時由系統隨機生成一個
1.2.1 網路位元組序與主機位元組序
網路位元組序與主機位元組序
1)主機位元組序就是我們平常說的大端和小端模式:不同的CPU有不同的位元組序型別,這些位元組序是指整數在記憶體中儲存的順序,這個叫做主機序。引用標準的Big-Endian和Little-Endian的定義如下:
- Little-Endian就是低位位元組排放在記憶體的低地址端,高位位元組排放在記憶體的高地址端。
- Big-Endian就是高位位元組排放在記憶體的低地址端,低位位元組排放在記憶體的高地址端。
2) 網路位元組序:4個位元組的32 bit值以下面的次序傳輸:首先是0~7bit,其次8~15bit,然後16~23bit,最後是24~31bit。這種傳輸次序稱作大端位元組序。由於TCP/IP首部中所有的二進位制整數在網路中傳輸時都要求以這種次序,因此它又稱作網路位元組序。
在將一個地址繫結到socket的時候,請先將主機位元組序轉換成為網路位元組序,而不要假定主機位元組序跟網路位元組序一樣使用的是Big-Endian。
1.3 listen()、connect()函式
如果作為一個伺服器,在呼叫socket()、bind()之後就會呼叫listen()來監聽這個socket,如果客戶端這時呼叫connect()發出連線請求,伺服器端就會接收到這個請求。
int listen(int sockfd, int backlog);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
listen函式:socket()函式建立的socket預設是一個主動型別的,listen函式將socket變為被動型別的,等待客戶的連線請求。
- sockfd即為要監聽的socket描述字
- backlog為相應socket可以排隊的最大連線個數。
connect函式
- sockfd即為客戶端的socket描述字
- addr為伺服器的socket地址
- addrlen為socket地址的長度。客戶端通過呼叫connect函式來建立與TCP伺服器的連線
1.4 accept()函式
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- sockfd 為伺服器的socket描述字
- addr為指向struct sockaddr *的指標,用於返回客戶端的協議地址
- addrlen為協議地址的長度。
如果accpet成功,那麼其返回值是由核心自動生成的一個全新的描述字,代表與返回客戶的TCP連線。
注意:accept的第一個引數為伺服器的socket描述字,是伺服器開始呼叫socket()函式生成的,稱為 監聽socket描述字;而accept函式返回的是 已連線的socket描述字。一個伺服器通常通常僅僅只建立一個監聽socket描述字,它在該伺服器的生命週期內一直存在。核心為每個由伺服器程式接受的客戶連線建立了一個已連線socket描述字,當伺服器完成了對某個客戶的服務,相應的已連線socket描述字就被關閉。
1.5 read(),write()等函式
read()/write()
recv()/send()
readv()/writev()
recvmsg()/sendmsg()
recvfrom()/sendto()
read函式是負責從fd中讀取內容.當讀成功時,read返回實際所讀的位元組數,如果返回的值是0表示已經讀到檔案的結束了,小於0表示出現了錯誤。
write函式將buf中的nbytes位元組內容寫入檔案描述符fd.成功時返回寫的位元組數。失敗時返回-1,並設定errno變數。
1.6 close()函式
完成了讀寫操作就要關閉相應的socket描述字int close(int fd);
2.TCP協議通訊流程
2.1 TCP三次握手
伺服器呼叫 socket()、bind()、listen() 函式完成初始化後,呼叫 accept() 阻塞等待,處於監聽埠的狀態,客戶端呼叫 socket() 初始化後,呼叫 connect() 發出 SYN 段並阻塞等待伺服器應答,伺服器應答一個SYN-ACK 段,客戶端收到後從 connect() 返回,同時應答一個 ACK 段,伺服器收到後從 accept() 返回。
2.2 TCP資料傳輸
TCP 連線建立後資料傳輸的過程:
建立連線後,TCP 協議提供全雙工的通訊服務,但是一般的客戶端/伺服器程式的流程是由客戶端主動發起請求,伺服器被動處理請求,一問一答的方式。因此,伺服器從 accept() 返回後立刻呼叫 read(),讀 socket 就像讀管道一樣,如果沒有資料到達就阻塞等待,這時客戶端呼叫 write() 傳送請求給伺服器,伺服器收到後從 read() 返回,對客戶端的請求進行處理,在此期間客戶端呼叫 read() 阻塞等待伺服器的應答,伺服器呼叫 write() 將處理結果發回給客戶端,再次呼叫 read() 阻塞等待下一條請求,客戶端收到後從 read() 返回,傳送下一條請求,如此迴圈下去。
2.3 四次揮手
如果客戶端沒有更多的請求了,就呼叫 close() 關閉連線,就像寫端關閉的管道一樣,伺服器的 read() 返回 0,這樣伺服器就知道客戶端關閉了連線,也呼叫 close() 關閉連線。注意,任何一方呼叫 close() 後,連線的兩個傳輸方向都關閉,不能再傳送資料了。如果一方呼叫 shutdown() 則連線處於半關閉狀態,仍可接收對方發來的資料
相關文章
- 淺談 TCP/IP 網路程式設計中 socket 的行為TCP程式設計
- Linux Socket C語言網路程式設計:TCP SocketLinuxC語言程式設計TCP
- Vector在Java程式設計中的應用 (轉)Java程式設計
- golang中的socket程式設計Golang程式設計
- Java Tcp協議socket程式設計學習JavaTCP協議程式設計
- linux下TCP socket程式設計初步(1)LinuxTCP程式設計
- (3)Tcp Socket程式設計的封裝類 TcpListener/TcpClientTCP程式設計封裝client
- 基於TCP協議的Socket網路程式設計( )TCP協議程式設計
- [譯] 設計 QA 在應用程式設計中的重要性程式設計
- python網路-Socket之TCP程式設計(26)PythonTCP程式設計
- 通過 Socket 實現 TCP 程式設計入門TCP程式設計
- Socket、TCP/IP、HTTP、FTP及網路程式設計TCPHTTPFTP程式設計
- Attribute在.net程式設計中的應用(一) (轉)程式設計
- Attribute 在.NET程式設計中的應用(二) (轉)程式設計
- Attribute在.NET程式設計中的應用(四) (轉)程式設計
- Attribute在.NET程式設計中的應用(五) (轉)程式設計
- Attribute在.NET程式設計中的應用(三) (轉)程式設計
- Linux系統程式設計(33)—— socket程式設計之TCP程式的錯誤處理Linux程式設計TCP
- Windows Socket程式設計精華《TCP通訊伺服器》Windows程式設計TCP伺服器
- Socket程式設計,從TCP分析到建立web網站程式設計TCPWeb網站
- Python 中的 Socket 程式設計(指南)Python程式設計
- 讀懂Java中的Socket程式設計Java程式設計
- 基於TCP/UDP的Socket程式設計,HTTP/HTTPS協議TCPUDP程式設計HTTP協議
- 函數語言程式設計及其在react中的應用函數程式設計React
- 設計模式及其在spring中的應用(含程式碼)設計模式Spring
- 設計模式在vue中的應用(六)設計模式Vue
- 設計模式在vue中的應用(七)設計模式Vue
- 設計模式在vue中的應用(五)設計模式Vue
- 設計模式在vue中的應用(三)設計模式Vue
- 設計模式在vue中的應用(四)設計模式Vue
- 設計模式在vue中的應用(一)設計模式Vue
- 設計模式在vue中的應用(二)設計模式Vue
- 設計模式,及在Java中的應用設計模式Java
- union 的概念及在嵌入式程式設計中的應用程式設計
- socket程式設計實現tcp伺服器_C/C++程式設計TCP伺服器C++
- [python3.3]Python非同步Socket程式設計【TCP】Python非同步程式設計TCP
- Qt 中Socket程式設計例項QT程式設計
- 聯合體在微控制器程式設計中的應用程式設計