1. 程式人生 > >網路程式設計基礎01 — 這些API要熟悉

網路程式設計基礎01 — 這些API要熟悉

1.Linux API
套接字相關:

#include <sys/types.h>
#include <sys/socket.h>

/* 功能:建立套接字;
 * 引數:domain - 協議族資訊:PF_INET:IPv4網際網路協議族;
 *                            PF_INET6:IPv6網際網路協議族;
 *                            PF_LOCAL:本地通訊的UNIX協議族;
 *                            PF_PACKET:底層套接字的協議族;
 *                            PF_IPX:IPX Novell協議族;
 *       type - 資料傳輸型別:SOCKET_STREAM:位元組流套接字;
 *                            SOCKET_DGRAM:資料報套接字;
 *                            SOCKET_RAW:原始套接字;
 *                            SOOCKET_SEQPACKET:有序分組套接字;
 *       protocol - 協議資訊:IPPROTO_TCP:TCP協議;
 *                            IPPROTO_UDP:UDP協議;
 *                            IPPROTO_SCTP:SCTP協議;
 * 返回:成功時返回套接字描述符,失敗時返回-1;
 */
int socket(int domain, int type, int protocol);


/* 功能:將IP地址和埠號繫結到套接字上;
 * 引數:sockfd - 套接字描述符;
 *       addr - 指向要繫結給sockfd的協議地址;
 *       addrlen - 地址的長度;
 * 返回:成功時返回0,失敗時返回-1;
 */
int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);


/* 功能:監聽套接字;
 * 引數:sockfd - 套接字描述符;
 *       backlog - 連線請求佇列中最大連線個數;
 * 返回:成功時返回0,失敗時返回-1;
 */
int listen(int sockfd, int backlog);


/* 功能:受理連線請求;
 * 引數:sockfd - 套接字描述符;
 *       clnt_addr - 客戶端的地址資訊;
 *       addrlen - 客戶端地址長度;
 * 返回:成功時返回新建立的與當前處理的連線對應的套接字描述符,失敗時返回-1;
 */
int accept(int sockfd, struct sockaddr *clnt_addr, socklen_t *addrlen);


/* 功能:客戶端請求與伺服器建立TCP連線;
 * 引數:sockfd - 套接字描述符;
 *       serv_addr - 伺服器的地址資訊;
 *       addrlen - 伺服器地址長度;
 * 返回:成功時返回0,失敗時返回-1;
 */
int connect(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen);

檔案讀寫相關:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/* 功能:開啟檔案;
 * 引數:path - 檔案全路徑;
 *       flag - 檔案開啟模式;
 * 返回:成功時返回檔案描述符,失敗時返回-1;
 */
int open(const char *path, int flag);


/* 功能:關閉檔案或套接字;
 * 引數:fd - 要關閉的檔案或套接字的檔案描述符;
 * 返回:成功時返回0,失敗時返回-1;
 */
int close(int fd);


/* 功能:寫
 * 引數:fd - 檔案/套接字描述符;
 *       buf - 要寫入的資料的起始地址;
 *       nbytes - 要寫入的位元組數;
 * 返回:成功時返回寫入的位元組數;失敗時返回-1;
 */
ssize_t write(int fd, const char *buf, size_t nbytes);


/* 功能:讀
 * 引數:fd - 檔案/套接字描述符;
 *       buf - 要儲存讀取資料的地址;
 *       nbytes - 要讀取資料的最大位元組數;
 * 返回:成功時返回讀取的位元組數,但遇到檔案結束符返回0;失敗時返回-1;
 */
ssize_t read(int fd, void *buf, size_t nbytes);

2.sockaddr和sockaddr_in
sockaddr是通用的socket地址,在#include <sys/socket.h>中定義,結構如下:

struct sockaddr
{
	unsigned short sa_family;
	char sa_data[14];
};

其中:
(1)sa_family表示地址族,長度為2B,形式為"AF_xxx",常用的值有:
AF_INET:IPv4地址資訊;
AF_INET6:IPv6地址資訊;
(2)sa_data表示協議地址資訊,長度為14B;

sockaddr_in在標頭檔案#include<netinet/in.h>或#include <arpa/inet.h>中定義,結構如下:

struct sockaddr_in
{
	short int sin_family;
	unsigned short int sin_port;
	struct in_addr sin_addr;
	unsigned char sin_zero[8];
};

其中:
(1)sin_family表示地址族,與sockaddr中的sa_family作用和取值一致;
(2)sin_port表示埠號,必須採用網路位元組序,長度為2B;
(3)sin_addr儲存IP地址,長度為4B;in_addr的結構定義如下:

struct in_addr
{
	union {
		struct {
			u_char s_b1, s_b2, s_b3, s_b4;
		} S_un_b;
		struct {
			u_short s_w1, s_w2;
		} S_un_w;
		u_long S_addr;
	} S_un;
	#define s_addr S_un.S_addr
};

(4)sin_zero是為了與struct sockaddr保持大小相同而保留的空位元組,長度為8B;
sockaddr_in將IP地址和埠號分開,方便賦值,網路程式設計中一般使用sockaddr_in定義和賦值,然後再強制轉換為sockaddr作為函式引數。

3.AF_INET與PF_INET
AF:Address Family,設定地址時使用AF_xxx;
PF:Protocol Family,建立socket時是指定協議,因此使用PF_xxx;
TCP/IP設計時認為某個協議族可能有多重形式的地址,即一個PF對應對個AF,因此做了上述區分;
但是實際上目前為止,一個PF只對應1個AF,沒有例外。
實質上,二者是相同的:
#define AF_INET PF_INET

4.Windows API

#include <winsock2.h>

/* 功能:設定winsock版本並初始化相關庫;
 * 引數:wVersionRequested - Winsock版本資訊;
 *       lpWSAData - WSADATA結構體變數的地址;
 * 返回:成功時返回0,失敗時返回非零的錯誤碼;
 */
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);


/* 功能:解除與socket庫的繫結並釋放系統資源;
 * 引數:無;
 * 返回:成功時返回0,失敗時返回SOCKET_ERROR;
 */
int WSACleanup(void);


// 返回:成功時返回套接字控制代碼,失敗時返回INVALID_SOCKET;
SOCKET socket(int af, int type, int protocol);


int bind(SOCKET s, const struct sockaddr *name, int namelen);


int listen(SOCKET s, int backlog);


// 成功時返回套接字控制代碼,失敗時返回INVALID_SOCKET;
SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen);


// 成功時返回0,失敗時返回SOCKET_ERROR;
int connect(SOCKET s, const struct sockaddr *name, int namelen);


/* 功能:關閉套接字;
 * 引數:s - 套接字控制代碼;
 * 返回:成功時返回0,失敗時返回SOCKET_ERROR;
 */
int closesocket(SOCKET s);


/* 功能:傳送資料;
 * 引數:s - 套接字控制代碼;
 *       buf - 待傳輸的資料地址;
 *       len - 要傳輸的位元組數;
 *       flags - 傳輸選項;
 * 返回:成功時返回傳輸的位元組數,失敗時返回SOCKET_ERROR;
 */
int send(SOCKET s, const char *buf, int len, int flags);


/* 功能:接收資料;
 * 引數:s - 套接字控制代碼;
 *       buf - 儲存接收資料的地址;
 *       len - 可以接收的最大位元組數;
 *       flags - 傳輸選項;
 * 返回:成功時返回傳輸的位元組數,失敗時返回SOCKET_ERROR;
 */
int recv(SOCKET s, char *buf, int len, int flags);