Linux網絡編程

 

Linux網絡編程

 

1 套接字地址結構

struct sockaddr{
unsigned short sa_family;//地址類型
char sa_data[14]; //14字節的地址協議
}

sa_family表示套接字的協議族類型,對應於TCP/IP的協議該是AF_INET;

與該結構體等價的另一個數據結構:sockaddr_in。

struct sockaddr_in

{

  unsigned short sin_family; //地址類型

  unsigned short sin_port ; //端口號

  struct in_addr sin_addr ;//IP地址

  unsigned char sin_zero[8];//填充字節,一般爲0 

}

struct in_addr {

  unsigned long s_addr;

};

結構體sockaddr和結構體sockaddr_in都是16個字節。通常在編寫基於TCP/IP協議的網絡程序的時候,使用sockaddr_in來設置地址,然後通過類型的強制轉換成sockaddr類型。

struct sockaddr_in sock;

sock.sin_family = AF_INET;

sock.sin_port = htons(80);

sock.sin_addr.s_addr = inet_addr("202.112.12.11");

memset(sock.sin_zero, 0, sizeof(sock.sin_zero)); //將數組sin_zero設置成爲0

 

2 創建套接字

#include <sys/types.h>

#include <sys/socket.h>

int socket(int domain, int type, int protocol);

domain用來表示套接字所使用的協議族。AF_UNIX:在本機通訊的套接字;AF_INET:使用ipv4; AF_INET6:使用ipv6。

type指示套接字的類型。SOCK_STREAM SOCK_DGRAM SOCK_RAW

 

3 建立連接

函數connect用來在一個執行的套接字上穿件一個連接。

#include <sys/types.h>

#include <sys/socket.h>

int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);

服務器的IP地址和端口號由serv_addr來制定。

 

4 綁定套接字

int bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);

這個函數只有服務器端使用。

5 在套接字上偵聽

int listen(int s, int backlog);

在服務器端,一般先創建一個socket,然後調用函數bind將該套接字綁定到某個端口上,接着調用listen函數等待來自於客戶端的連接請求。

一般多個客戶端連接到一個服務器,服務器設置一個連接隊列,記錄已經建立的連接,參數backlog指定了該連接隊列的最大長度。如果連接隊列已經達到最大,

之後的連接請求將會被服務器拒絕。

6 接受連接

int accept(int s, struct sockaddr *addr, socklen_t *addrlen);

參數s是由函數socket創建,經函數bind綁定到本地某一端口上,然後通過函數listen轉化而來的監聽套接字。

參數addr是用來保存發起連接請求的主機的地址和端口。

參數addrlen是addr所指向的結構體的大小。

只能對面向連接的套接字使用accept函數。accept成功時,將創建一個新的套接字,併爲這個新的套接字分配一個新的套接字描述符,類似文件描述符,進程可以利用這個新的套接字描述符與客戶端交換數據。參數S指定的套接字將繼續等待客戶端的連接請求。

如果參數s指向的套接字被設置成爲阻塞方式(Linux默認的設置),且連接請求隊列爲空的時候,則accept函數將被阻塞直到有連接請求爲止;

如果參數s指向的套接字被設置成爲非阻塞方式(fcntl),如果隊列爲空,則accept立即返回-1,errno設置成爲EAGAIN。

7 TCP套接字 發送數據

size_t send(int s, const void *msg, size_t len, int flags);

函數send只能對處於連接狀態的套傑斯使用。參數S爲已建立好連接的套接字描述符,即accept函數的返回值。

參數msg指向存放待發數據的緩衝區,參數len爲待發數據的長度。

如果要發送的數據太長而不能發送時,將出現錯誤,error設置成爲EMSGSIZE;

如果要發送的數據長度大於該套接字的緩衝區剩餘空間大小時,send()一般會被阻塞,如果該套接字設置成爲非阻塞方式,則此時立即返回-1.

執行成功則返回實際發送的數據的字節數。

執行成功只能說明數據寫入套接字的緩衝區中,並不表示數據已經成功的通過網絡發送到目的地。

8 接受數據

size_t recv(int s, coid *buf, size_t len, int flags);

如果一個數據包太長以至於緩衝區放不下的時候,剩餘部分的數據將可能被丟棄。

如果在指定的套接字上無數據到達時,recv函數將被阻塞,如果套接字設置成爲非阻塞的話,則立即返回-1;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章