《網路多人遊戲架構與程式設計》之伯克利套接字
阿新 • • 發佈:2022-05-27
一、建立、銷燬、繫結、傳送、接收
SOCKET socket(int af,int type,int protocol);
af: 協議簇
type: 通過socket傳送和接收分組的形式
protocol:socket應使用的協議,包括傳輸層協議、各種實用網路層協議。
///////////////建立SOCKET/////////////////
建立1個IPV4 UDP socket : SOCKET udpSocket = socket( AF_INET, SOCK_DGRAM, 0);
建立1個TCP socket:SOCKET tcpSocket = socket( AF_INET, SOCK_STREAM, 0);
///////////停止傳輸和接收SOCKET//////////
int shutdown(SOCKET sock, int how);
————————————
how: SD_SEND 停止傳送;產生FIN資料包,所有資料傳送後傳送這個資料包,通知另一端關閉socket,然後另一端會回一個FIN資料包,我們就可以關閉socket了。
SD_RECEIVE 停止接收
SD_BOTH 停止傳送和接收
///////////////關閉SOCKET/////////////////
關閉不考慮型別:int closesocket (SOCKET sock);
————————————
Tips:關閉前保證所有傳送的和接收的資料都已經傳輸和確認。
///////////////繫結SOCKET/////////////////
返回值:0 成功 ; -1 錯誤
///////////////UDP傳送資料/////////////////
int sendto(SOCKET sock, const char *buf, int len, int flags, const sockaddr *to, int tolen);
buf:指向待發送資料起始地址的指標;
len:待發送資料的大小;避免傳送大於1300位元組的資料包。
flags:對傳送標誌進行按位或運算的結果,遊戲中通常是0。
to:接收端的sockaddr。
tolen:to指向的sockaddr的大小。對於IPV4,等於sizeof(sockaddr_in)。
返回值:成功:等待發送資料長度; 失敗:-1。
///////////////UDP接收資料/////////////////
int recvfrom(SOCKET sock, const char *buf, int len, int flags, const sockaddr *from, int *fromlen);
buf:接收的資料包的緩衝區;
len:buf可以儲存的最大位元組數。
flags:對接收標誌進行按位或運算的結果,遊戲中通常是0。
from:指向sockaddr的指標。
fromlen:from指向的sockaddr的大小。
返回值:成功:複製到buf的位元組數; 失敗:-1。
///////////////TCP啟動監聽/////////////////
int listen(SOCKET sock, int backlog);
backlog:允許傳入的最大連線數。SOMAXCONN表示預設值。
返回值:成功 0;錯誤 -1。
///////////////TCP接收連線/////////////////
SOCKET accept(SOCKET sock, sockaddr *addr, int *addrlen);
///////////////TCP發起連結/////////////////
SOCKET connect(SOCKET sock, const sockaddr *addr, int *addrlen);
///////////////TCP傳送資料/////////////////
int send(SOCKET sock, const char *buf, int len, int flags);
///////////////TCP接收資料/////////////////
int recv(SOCKET sock, char *buf, int len, int flags);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
二、阻塞和非阻塞I/O
三種解決執行緒阻塞的辦法:
非阻塞I/O
select函式
巨集 | 含義 |
AF_UNSPEC | 未指定 |
AF_TNET | IPV4 |
AF_IPX | 分組交換 |
AF_APPLETALK | Appletalk協議 |
AF_INET6 | IPV6 |
巨集 | 含義 |
SOCK_STREAM | 有序的、可靠的資料流分段 |
SOCK_DGRAM | 離散的報文 |
SOCK_RAW | 包頭可以由應用層自定義 |
SOCK_SEQPACKET | 類似SOCK_STREAM,但要整體讀取資料包 |
巨集 | 需要的型別 | 含義 |
IPPROTO_UDP | SOCK_DGRAM | UDP資料報 |
IPPROTO_TCP | SOCK_STREAM | TCP報文段 |
IPPRPTO_IP/0 | Any | 實用預設協議 |
- 多執行緒
- 目的:給每一個可能的阻塞呼叫生成一個執行緒:每個客戶端1個,監聽1個...
- 缺點:每個客戶端需要1個執行緒,不利於擴充套件和管理。
- 使用ioctlsocket設定socket為非阻塞模式:int ioctlsocket(SOCKET sock, long cmd, u_long *argp); //cmd是控制引數;argp是該引數的取值,0阻止開啟非阻塞,其他值開啟。
- 優點:每幀檢查是否有準備好的待接收資料,有,先處理第一個掛起;沒有,進行到下一幀,沒有等待。
- 缺點:輪詢的socket數量很大時,效率很低。
- 優點:可以同時檢查多個socket,只要有1個準備好了就開始執行