套接字(socket)是一種通訊機制,憑藉這種機制,客戶/服務器系統的開發工作既可以在本地單機上運行,也可以跨網絡運行。
創建套接字
socket系統調用創建一個套接字返回一個描述符,該描述符可以用來訪問該套接字
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
創建的套接字是一條通信線路的一個端點。domain參數自定協議族,type參數指定套接字的通信類型,protocol參數指定使用的協議。
domain信號可指定的協議族:
域 | 說明 |
AF_UNIX | UNIX域協議(文件系統套接字) |
AF_INET | ARPA因特網協議(UNIX網絡套接字) |
AF_ISO | ISO標準協議 |
AF_NS | 施樂(Xerox)網絡系統協議 |
AF_IPX | Novell IPX協議 |
AF_APPLETALK | Appletalk DDS |
AF_UNIX和AF_INET前者用於通過UNIX和Linux文件系統實現本地套接字後者用於UNIX網絡套接字。
type指定用於指定套接字的特性,取值包括SOCK_STREAM和SOCK_DGRAM,對於AF_INET域來說 TCP、UDP
protocol該參數設置爲0,表示默認協議。
套接字地址
每個套接字域都有自己的地址格式。對於AF_UNIX域套接字來說,它的地址由結構sockaddr_un來描述,該結構定義在頭文件sys/un.h
struct sockaddr_un{
sa_family_t sun_family; /*AF_UNIX*/
char sun_path[]; /*pathname*/
}
linux中sun_path路徑名的長度限制爲108個字符,因爲地址結構長度不一致,所以許多套接字調用需要用到一個複製特定地址長度變量或將它作爲一個輸出。
在AF_INET域中,套接字地址由結構sockaddr_in來指定,該結構定義在頭文件netinet/in.h中,它至少包含以下接成員:
struct sockaddr_in{
short int sin_family; /*AF_INET*/
unsigned short int sin_port; /*Port number*/
struct in_addr sin_port; /*Internet address*/
}
struct in_addr{
unsigned long int s_addr;
}
命名套接字
創建的套接字要想被其它進程使用,服務器程序就必須給套接字命名,AF_UNIX關聯到一個文件系統的路徑名,AF_INET會關聯到一個IP的端口號。
#include <sys/socket.h>
int bind(int socket, const struct sockaddr * address, size_t address_len);
bind系統調用把參數address中的地址分配給文件描述符socket關聯的未命名套接字。地址結構的長度由address_len傳遞。
地址的長度和格式取決於地址族。bind調用需要將一個特定的地址結構指針轉換爲指向通用地地址類型(struct sockaddr *)。
創建套接字隊列
爲了能夠在套接字上接收進入的連接,服務器程序必須創建一個隊列來保護未處理的請。它用listen系統調用來完成這一工作。
#include <sys/socket.h>
int listen(int socket, int backlog);
參數backlog用於對隊列中未處理的連接數做限制
接收連接
一旦服務器程序創建並命名套接字後,之後就可以通過accept系統調用來等待客戶對該套接字的連接。
#include <sys/scoket.h>
int accept(int socket, struct sockaddr *address, size_t *address_len);
accpet系統調用只有當有客戶程序試圖連接到有socket參數指定的套接字上時才返回。這裏的客戶是指,在套接字隊列中排在第一個未處理連接。accept函數函數將創建一個新的套接字來與該客戶進行通信,並且返回新套接字的描述符。
請求連接
客戶程序通過一個未命名的套接字和服務器監聽套接字之間建立建立連接的方法來連接到服務器。它們通過connect調用來完成這一工作。
#include <sys/socket.h>
int connect(int socket, const struct sockaddr *address, size_t address_len);
參數socket指定的套接字將連接到參數address指定的服務器套接字,address指向結構體的長度由address_len指定,參數socket指定的套接字必須通過socket調用獲得的一個有效的文件描述符。
成功時,connect調用返回0,失敗時返回-1。
關閉套接字
可以通過close函數來終止服務器和客戶上的套接字連接。