lwip网络通信socket_lwIP在Socket模式下接口:BSD Socket API
http://home.eeworld.com.cn/my/space-uid-162102-blogid-52270.html
2011
原文:
關于BSD Socket API
在網上找到的兩個網站,是關于BSD Sockets API的,這是與lwIP在Socket模式下兼容的。里面對API函數做了較為詳細的介紹,先記下來,有空翻譯一下
-------------------------------------------------------------------------------------
最常用的BSD API函數:
socket:創建一個插口(socket)
bind:將本地端口號和IP地址綁定到插口上
listen:TCP監聽
accept:TCP監聽接受處理
connect:TCP客戶端連接
select:特殊插口設置
send/sendto:發送數據包到已連接/未連接插口上
recv/recvfrom:接收數據包從已連接/未連接插口上
getsockopt/setsockopt:獲取/改變插口選項
getpeername/getsockname:獲取遠端/本地地址信息
close:關閉插口
shutdown:按設置關閉插口
gethostbyname/gethostbyaddr:地址域名映射
read:從插口緩存讀數據
write:想插口緩存寫數據
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
#include
#include
int socket( int domain, int type, int protocol );
創建通訊用的“插口”(插口socket可以理解為IP地址和端口號組合成的地址),創建成功返回插口ID(出錯返回-1)。
參數:domain協議族(AF_UNIX是UNIX,AF_INET是IPv4協議,AF_ROUTE是路由器協議);type類型(SOCK_STREAM是TCP,SOCK_DGRAM是UDP,SOCK_RAW是RAM活IPv4);protocol為0。
該函數返回大于等于0的整數作為插口ID,如果出錯返回-1
-------------------------------------------------------------------------------------
#include #include
int bind ( int sockFd, const struct sockaddr *sockAddr, int addrLen );
將插口名、本地端口號和本地IP地址綁定到指定插口上。一般在用作服務器時使用該函數。返回0成功,-1未成功。
參數:sockFd插口ID,由socket函數創建;sockAddr結構體包含插口地址信息,AF_UNIX用下面結構體
struct sockaddr {
unsigned short sa_family;???? // Address Family (domain)
char?????????? sa_data[14]]; // Protocol Address
};
AF_INET用下面的結構體,使用前需初始化,下面使用TCP函數時相同。
struct sockaddr_in {
short????????? sin_family;??? // Address Family
unsigned short sin_port;????? // Port Number
struct in_addr sin_addr;????? // Internet Address
unsigned char sin_zero[8];?? // Pad structure
};
addrLen是上述結構體長度。
-------------------------------------------------------------------------------------
#include
int listen( int sockFd, int backlog );
TCP服務器監聽指定插口
參數:sockFd已創建并被綁定的插口;backlog允許接收的客服端數量。
-------------------------------------------------------------------------------------
include
#include
int accept ( int sockFd, struct sockaddr *clientAddr, int *addrLen )
TCP服務器監聽到連接時的響應函數。
參數:sockFd已創建、綁定并監聽的插口;clientAddr遠端連接信息;addrLen結構體長度。
-------------------------------------------------------------------------------------
#include
#include
int connect ( int sockFd, struct sockaddr *servAddr, int addrLen );
TCP/UDP客服端申請TCP/UDP服務器的鏈接。
參數:sockFd已創建的插口;servAddr服務器連接信息;addrLen結構體長度。
返回0成功,-1出錯
-------------------------------------------------------------------------------------
#include
#include
#include
int select( int n, fd_set *read_fds, fd_set *write_fds,
fd_set *exceptfds, struct timeval *timeout );
掛起當前線程,等待特定事件發生或定時器過期。本函數可以指定4類特定事件:read、write、exception和超時。返回插口ID表示事件有響應,0表示超時,-1表示出錯。
參數:n應該大于所有插口ID,用FD_SETSIZE代替;后面三個fd_set結構體存儲三種插口事件位圖:
typedef struct fd_set {
fd_mask fds_bits[(FD_SETSIZE + NFDBITS - 1) / NFDBITS];
} fd_set;
用以下四個宏修改:
FD_SET(fd, fdset) fd插口ID,fdset是fd_set結構體地址,設置插口事件為真
FD_CLR(fd, fdset)設置插口事件為假
FD_ISSET(fd, fdset)獲取插口狀態,是否設置
FD_ZERO(fdset)清除所有設置
第四個參數timeval結構體如下:
struct timeval {
int tv_sec;????? /* 秒 */
int tv_usec;???? /* 毫秒 */
};
用來設置超時時間。
-------------------------------------------------------------------------------------
#include
#include
int send ( int sockFd, const void *msg, int msgLen, unsigned int flags);
int sendto ( int sockFd, const void *msg, int msgLen, unsigned int flags,
const struct sockaddr *to, int toLen);
這兩個函數都用來按插口發送數據包,send用在已經連接的插口,sendto用在沒有連接上的插口。
send函數的參數:sockFD插口ID,msg要發送的數據指針,msgLen要發送的數據長度,flags發送選項(按位)
sendto函數的參數:UDP專用,插口必須是SOCK_DGRAM類型。由于沒有連接,所以sendto函數增加了兩個與連接有關的參數。to定義目標地址的結構體,toLen是結構體長度。sockaddr結構體如下:
struct sockaddr {
u_short sa_family;
char sa_data[14];
};
這兩個函數返回值均為實際發送字節的長度(軟件需要調整偏移量將數據全部發送),-1表示發送不成功。
-------------------------------------------------------------------------------------
#include
#include
int recv ( int sockFd, const void *msg, int msgLen, unsigned int flags);
int recvfrom ( int sockFd, const void *msg, int msgLen, unsigned int flags,
const struct sockaddr *from, int *fromLen);
這兩個函數均是按插口來接收數據包,recv函數用在已連接插口上,recvfrom用在未連接插口上。
recv函數參數:sockFd插口ID,msg接收緩存地址,msgLen接收緩存最大空間,flags接收選項。
recvfrom函數參數:UDP專用,插口必須是SOCK_DRAM類型。由于沒有連接,所以recvfrom函數增加了兩個與連接有關的參數。from定義目標地址的結構體,formLen是結構體長度。
兩個函數均返回接收到的數據數,-1接收錯誤,0表示目標地址已經傳輸完畢并關閉連接。
-------------------------------------------------------------------------------------#include
#include
int setsockopt ( int sd, int level, int optname, const void *optval, socklen_t optlen);
int getsockopt ( int sd, int level, int optname, void *optval, socklen_t *optlen );setsockopt函數用來改變插口的模式,這種改變是通過修改插口選項實現的。getsockopt函數用來獲取插口選項的值。參數:sd插口ID;level協議棧選項,包括SOL_SOCKET(插口層)、IPPROTO_TCP(TCP層)和IPPROTO_IP(IP層);optname需要修改的選項名;optval修改值地址;optlen修改值長度。返回0表示成功。-------------------------------------------------------------------------------------#include int getsockname ( int sd, struct sockaddr *addr, int *addrLen );int getpeername ( int sd, struct sockaddr *addr, int *addrLen );getsockname函數用于從已連接的插口中獲取本地地址信息。getpeername函數用于獲取遠端地址信息。參數:sd插口ID;addr地址信息結構體;addrLen結構體長度。返回0成功,-1錯誤-------------------------------------------------------------------------------------#include int close ( int sd );關閉插口通信(丟棄未發送的數據包并拒絕接受數據)-------------------------------------------------------------------------------------#include int shutdown ( int sockFd, int how );該函數提供了更大的權限控制插口的關閉過程。參數:sockFd插口ID;how僅能為0、1和2這三個值0表示停止接收當前數據并拒絕以后的數據接收1表示停駛發送數據并丟棄未發送的數據2是0和1的合集-------------------------------------------------------------------------------------intread(int sockFD, void *buffer, UInt32 numBytes);從指定插口中等待數據接收并存放到buffer中。該函數會掛起線程,直到有數據接收到。參數:sockFd插口ID;buffer緩存地址;numBytes緩沖大小該函數返回接收到的數據大小,-1表示出錯,0表示遠端已經關閉連接。-------------------------------------------------------------------------------------int write(int sockFD, void *buffer, UInt32 numBytes);將緩存中數據寫到指定插口準備發送。參數:sockFd插口ID;buffer緩存地址;numBytes緩存中數據大小該函數返回實際發送的數據量,-1表示出錯。-------------------------------------------------------------------------------------補充:lwIP協議棧在socket模式下也就是操作系統中運行,創建進程的方式與操作系統中創建進程的方式有所不同。要用專用函數:sys_thread_t sys_thread_new(char *name, void(* thread)(void *arg), void *arg, int stacksize, int prio)參數:name線程說明;thread線程函數;arg線程函數的參數;stacksize線程堆棧大小;prio線程優先級在lwIP下創建線程統一使用此函數,當然這個函數也是要調用系統創建線程的API的。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的lwip网络通信socket_lwIP在Socket模式下接口:BSD Socket API的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mybatis那些事~
- 下一篇: 排序算法之--桶排序(桶,像桶一样的排序