插板插座
網路套接字
在通訊過程中,套接字一定是成對存在的
兩份套接字,c乙個 s乙個
乙個檔案描述符指向乙個套接字(該套接字內部由核心借助兩個緩衝區實現)
網路位元組序
大端法
例如udp段格式,位址0-1是16位的源埠號,如果這個埠號是1000 (0x3e8), 則位址0是0x03, 位址1是0xe8, 也就是先發0x03,再發0xe8,這16位在傳送主機的緩衝區中也應該是低位址存0x03, 高位址存0xe8。但是,如果傳送主機是小端位元組序的,這16位被解釋成0xe803, 而不是1000。 因此,傳送主機把1000填到傳送緩衝區之前需要做位元組序的轉換。同樣地,接收主機如果是小端位元組序的,接到16位的源埠號也要做位元組序的轉換。如果主機是大端位元組序的,傳送和接收都不需要做轉換。同理,32位的ip位址也要考慮網路位元組序和主機位元組序的問題。
htonl 是將本地的32位整型數轉換為網路位元組序。 主要是用於ip的轉換。
192.168.1.11 --> string -->atoi -->int -->htonl -->網路位元組序
int inet_pton (int af ,const char *src, void *dst)
af 指代當前協議,ipv4 (af_inet)或者ipv6 (af_inet6)
src 傳入ip位址 (點分十進位制)
dst 傳出 轉換後的 網路位元組序的ip位址
返回值:
成功:1
失敗: -1
const char *inet_ ntop(int af,const void * src, char * dst, socklen_t size);網路位元組序--->本地位元組序(string ip)af: af_inet、af_inet6src:網路位元組序ip位址dst:本地位元組序(string ip) size: dst 的大小。
返回值:成功:dst
失敗 : null
struct sockaddr_in add;第乙個引數add.sin_family = af_inet
第二個引數add.sin_port = htons(8080);
第三個引數是結構體add.sin_addr.s_addr
但是一般是用add.sin_addr.s_addr = htonl( inaddr_any) (取出系統中任意有效的ip位址,是二進位制型別,所以用htonl進行轉換)
流程
tcp服務端同socket函式生成乙個套接字,套接字中有檔案描述符,這個檔案描述符相當於控制代碼,乙個入口。然後呼叫bind()函式將埠號和ip繫結,再呼叫listen() listen的作用是設定監聽上限,就是乙個引數設定。再進行呼叫accept()是阻塞監聽客戶端連線。accept的引數中包含著之前用socket()生成的套接字的控制代碼。然後accept函式會返回乙個新的socket()。這個新的socket 和客戶端的套接字進行通訊。
tcp客戶端通過socket()新建了乙個套接字,然後通過connect()進行連線。connect()中要繫結ip和port 。此時服務端和客戶端就連線在了一起,整個系統中存在三個socket(),一對和乙個獨立的,一對的是進行連線通訊的,單獨的那個是進行監聽的。
int socket(int domain, int type, int protocol);domain是指定當前的ip協議是哪個,例如我們選擇af_inet即ipv4.
type指定當前套接字的資料傳輸協議。期中有流式傳輸stream, 報式協議sock_dgram
protocol : 表示所選協議中的代表協議,一般我們都是傳0.
舉例: type的引數是stream時,protocol的引數是0,就表示當前協議是tcp,如果type是dgram,protocol的引數是0,就表示單前協議是udp
返回值:如果成功就返回新套接字所對應的檔案描述符。
失敗就是 -1 errno。
舉例:fd= socket(af_inet,sock_stream,0) 就是返回乙個ipv4的tcp協議的套接字。
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);給socket 繫結乙個位址結構(ip+port)
sockfd 就是socket函式返回值
addr 就是sockaddr 位址結構,要分別對三個引數進行初始化。
這個結構體和引數中需要的結構體不同,所以初始化完了之後要進行強轉。
例如:
struct sockaddr_in addr ;返回值:addr.sin_family = af_inet; //(和前面使用的ip協議相同)
addr.sin_port = htons(8080);
addr.sin_addr.s_addr = htonl(inaddr_any);
addr :(struct sockaddr *) &addr ;
addrlen :sizeof(addr) 位址結構的大小
成功: 0
失敗: -1 errno
int listen(int sockfd, int backlog);設定同時與伺服器建立連線的上限數(同時進行三次握手的客戶端數量)
sockfd: socket的控制代碼
backlog : 上限數值, 最大值為128
成功:返回0
失敗: 返回-1
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);阻塞等待客戶端建立連線,成功返回乙個與客戶端成功連線socket檔案描述符。用乙個socket返回乙個新socketsockfd: socket的控制代碼#define _gnu_source /* see feature_test_macros(7) */
#include
int accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags);
addr : 和bind 的引數差乙個關鍵字const ,上乙個是傳入引數,這個是傳出引數,即傳出的是成功與伺服器建立連線的那個客戶端的位址結構。
addrlen : 入:addr的大小 出:客戶端addr的實際大小
返回值:
成功:能與客戶端進行資料通訊的socket對應的檔案描述。
失敗: -1 errno
乙個埠肯定只能繫結乙個socket。伺服器端的埠在bind的時候已經繫結到了監聽套接字socetfd所描述的物件上,accept函式新建立的socket物件其實並沒有進行埠的占有,而是複製了socetfd的本地ip和埠號,並且記錄了連線過來的客戶端的ip和埠號。
那麼,當客戶端傳送資料過來的時候,究竟是與哪乙個socket物件通訊呢?
客戶端傳送過來的資料可以分為2種,一種是連線請求,一種是已經建立好連線後的資料傳輸。
由於tcp/ip協議棧是維護著乙個接收和傳送緩衝區的。在接收到來自客戶端的資料報後,伺服器端的tcp/ip協議棧應該會做如下處理:如果收到的是請求連線的資料報,則傳給監聽著連線請求埠的socetfd套接字,進行accept處理;如果是已經建立過連線後的客戶端資料報,則將資料放入接收緩衝區。這樣,當伺服器端需要讀取指定客戶端的資料時,則可以利用socketfd_new 套接字通過recv或者read函式到緩衝區裡面去取指定的資料(因為socketfd_new代表的socket物件記錄了客戶端ip和埠,因此可以鑑別)。
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);與伺服器建立連線。
sockfd : 客戶端socket函式返回值。
addr : 傳入引數, 伺服器的位址結構 。
返回值:
成功 :0
失敗: -1 errno
這邊不使用bind 函式進行繫結的話,就採用了「隱式繫結」。
tcp通訊流程分析:
server:
socket( ) 建立socket
bind ( ) 繫結伺服器位址結構
listen( ) 設定監聽上限
accept() 阻塞監聽客戶端連線
read (fd) 讀socket獲取客戶端資料
小--大寫 toupper ()
write(fd)
close()
client:
socket() 建立socket
connect( ) 與伺服器建立連線
write ( ) 寫資料到socket
read() 讀轉換後的資料。
顯示讀取結果
close
Socket學習筆記
public classsocketextends object 此類實現客戶端套接字 也可以就叫 套接字 套接字是兩台機器之間的通訊端點。套接字的實際工作由socketimpl類的例項執行。應用程式通過更改建立套接字實現的套接字工廠可以配置它自身,以建立適合本地防火牆的套接字。一 建構函式 soc...
socket學習筆記
為了理清思路,做一些小筆記 1 socket流程 int socket 產生了該socket的描述符socket description bind 主動呼叫時,把socket與埠繫結,如果不主動呼叫,在linsten和connect時,會自動隨機分配乙個埠。server端在socket和bind之後...
socket程式設計(學習筆記)
tcp ip協議找到目標位址,埠號標識軟體。public static void main string args throws exception 客戶端 public static void main string args 多執行緒通訊 構造執行緒,執行邏輯 thread thread 1 n...