socket通訊
網絡字節序
- 小端法: 高位存高地址,低位存低地址。 (intel架構的存儲方式)
- 大端法:高位存低地址,低位存高地址。(網絡傳輸的方式)
#include <arpa/inet.h>
// 將本地轉網絡,轉IP 轉192.168.1.11->string->atoi->int->htonl->網絡字節序,可以使用 int inet_pton(); 進行直接轉換
uint32_t htonl(uint32_t hostlong);
// 本地轉網絡,轉port
uint16_t htons(uint16_t hostshort);
// 網絡轉本地,轉ip
uint32_t ntohl(uint32_t netlong);
// 網絡轉本地,轉port
uint16_t ntohs(uint16_t netshort);
// string轉網絡字節
int inet_pton(int af, const char * restrict src, void * restrict dst);
// af: AF_INET, AF_INET6
// src: ip地址,點分十進制
// dst: 轉換之后的 網絡字節序的地址
創建socket服務器的步驟
- 創建socket句柄
- bind() 綁定ip+port
- listen() 設置監聽上線,同時連接數
- accept() 阻塞監聽客戶端連接
- read() 進行數據的讀取,讀取到的數據需要toupper()進行小寫轉大寫
- write() 寫入,寫給客戶端返回值
- 當read()讀到0就是close的時候進行 close() 關閉
Socket函數分析
創建一個套接字
int socket(int domain, int type, int protocol);
- domain : 所選用的ip地址協議, AF_INET, AF_INET6
- type : 類型 SOCK_STREAM(TCP/流形式), SOCK_DGRAM(UDP/報形式)
- protocol : 代表協議號 0
返回值:
成功返回0,新套接字的文件描述
失敗返回: -1
#include <sys/socket.h>
fd = socket(AF_INET, SOCK_STREAM, 0)
sockaddr地址結構體分析
#include <sys/socket.h>
#include <arpa/inet.h>
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9527);
int dst;
inet_pton(AF_INET, "192.168.22.45", (void *)&dst);
addr.sin_addr.s_addr = dst;
addr.sin_addr.s_addr = htonl(INADDR_ANY) // INADDR_ANY 取出系統有效的任意ip地址,是二進制類型
bind(fd, (struct sockaddr *)&addr, size);
bind函數的分析
綁定函數
bind(fd, (struct sockaddr *)&addr, size);
- fd : socket文件對象
- (struct sockaddr *)&addr : 將sockaddr存儲的地址結構進行強制轉換成sockaddr 進行傳入
- size : addr的大小,使用sizeof進行獲取
listen函數分析
監聽函數
int listen(int sockfd, int backlog);
- sockfd : 套接字
- backlog : 最大連接數,最大為128
- 返回值: 0, -1 error
accept函數分析
堵塞函數
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- sockfd : socket 函數返回值
- addr : 傳出參數, 成功返回服務器的ip和端口號
- addrlen : 傳入傳出。入: addr的大小。 出:客戶端addr的實際大小
返回值:
- 成功: 大於0,返回成功的套接字文件描述符
- 失敗:返回-1
connect函數分析
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 使用現有的socket與服務器建立連接
- sockfd: socket 函數返回值
- addr: 傳入服務器的地址結構
- 返回值:
- 成功:0
- 失敗:-1