Tcp/Ip協議理解_3
阿新 • • 發佈:2018-11-21
linux 一切皆檔案。 socket是可讀可寫可控可關閉的檔案描述符
1.建立socket
#include<sys/types.h> #include<sys/socket.h> int socket(int domain,int type,int protocol);
- domain 告訴系統使用哪個底層協議族 對於tcp/ip PF_INET
- type 服務型別 SOCK_STREAM(資料流 SOCK_DGRAM(資料報
- protocol 0 使用預設協議
2.命名socket
#include<sys/types.h> #include<sys/socket.h> int bind(int sockfd,const struct sockaddr*my_addr,socklen_t addrlen);
-
bind將my_addr所指的socket地址分配給未命名的sockfd檔案描述
符,addrlen引數指出該socket地址的長度。 - 通常伺服器需要命名socket (只有命名後 客戶端才知道如何連線
3.監聽socket
#include<sys/socket.h> intlisten(int sockfd,int backlog);
- sockfd引數指定被監聽的socket
-
backlog引數提示核心監聽佇列的最大長度 (通常5(超過backlog 伺服器不受理新的客戶連線
4.接受連線
- 從listen監聽佇列中接受一個連線
#include<sys/types.h> #include<sys/socket.h> int accept(int sockfd,struct sockaddr*addr,socklen_t*addrlen);
- sockfd引數是執行過listen系統呼叫的監聽socket
-
addr引數用來獲取被接受連線的遠端socket地址
-
該socket地址的長度由addrlen引數指出
5.發起連線
- 客戶端主動與伺服器建立連線
#include<sys/types.h> #include<sys/socket.h> int connect(int sockfd,const struct sockaddr*serv_addr,socklen_t addrlen);
- sockfd引數由socket系統呼叫返回一個socket
-
serv_addr引數是伺服器監聽的socket地址,addrlen引數則指定這個地址的長度
- connect成功時返回0。一旦成功建立連線,sockfd就唯一地標識了
- 這個連線,客戶端就可以通過讀寫sockfd來與伺服器通訊。connect失敗
- 則返回-1並設定errno。其中兩種常見的errno是ECONNREFUSED和
- ETIMEDOUT
6.關閉連線
- 關閉一個連線實際上就是關閉該連線對應的socket
#include<unistd.h> int close(int fd);
- fd引數是待關閉的socket
- 並非立即關閉 通過將fd的引用計數-1 0真正關閉
立即終止連線(不通過引用計數
- 可以使用shutdown
#include<sys/socket.h> int shutdown(int sockfd,int howto);
- sockfd引數是待關閉的socket
- howto引數決定了shutdown
7.TCP資料讀寫
- recv讀取sockfd上的資料 send 往sockfd寫資料
- buf和len引數分別指定讀緩衝區的位置和大小
- flags引數的含義見後文,通常設定為0即可
- recv成功時 返回實際讀取到的資料長度
8.UDP資料讀寫
#include<sys/types.h> #include<sys/socket.h> ssize_t recvfrom(int sockfd,void*buf,size_t len,int flags,struct sockaddr*src_addr,socklen_t*addrlen); ssize_t sendto(int sockfd,const void*buf,size_t len,int flags,const struct sockaddr*dest_addr,socklen_t addrlen);
- recvfrom /sendto讀/寫sockfd上的資料
- buf和len引數分別指定讀緩衝區的位置大小
- 每次讀取資料都需要獲取傳送端的socket地址 src_addr
- addrlen引數指定該地址的長度
- flags引數以及返回值的含義均與send/recv系統呼叫 的flags相同