一.使用Socket,首先需要導入這幾個系統頭文件
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
二.然后就是進行Socket代碼的編寫,先來看看實現一個簡單的Socket通信需要哪些步驟:
>1.創建客戶端Socket;
>2.創建服務器Socket;
>3.連接兩個Socket;
>4.客戶端Socket發送信息給服務器(發送請求的過程);
>5.服務器響應客戶端的請求,返回給客戶端數據(服務器響應的過程);
>6.客戶端接受服務器返回的數據;
>7.關閉Socket;
三.下面要進行詳細的Socket代碼實現了.
1.創建客戶端Socket
//參數1:協議域: 遵守的IP協議類型! AF_INET:IPv4 AF_INET6:IPv6
//參數2:端口類型: TCP:SOCK_STREAM UDP:SOCK_DGRAM
// 參數3: 選擇的協議類型! 一般傳0 會根據第二個參數自動選擇協議類型!
// 返回值: 如果返回值>0 ,標示 Socket 創建成功!
int SocketNumber = socket(AF_INET,SOCK_STRESM,0);
2. 創建服務器端 Socket
struct sockaddr_in serverAddress;
// 主機 /端口
// 設置 服務器Socket 遵循的 IP 協議類型為 IPv4
serverAddress.sin_family = AF_INET;
// 服務器 Socket 的 IP 地址
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
// 設置服務器Socket 的端口號;
// 端口號的最大值 65535; 09~1024 是系統默認占用的端口號!不要設置!
// 如果需要手動設置端口號: 一般設置 1024 ~ 65535 之間的值!
serverAddress.sin_port = htons(3456);
3. 連接兩個 Socket
// 參數1: 客戶端的 Socket
// 參數2: 服務器端 Socket/結構體 (const struct sockaddr *)&serverAddress 強制類型轉換
// 參數3: 第二個參數的長度! sizeof(serverAddress) 計算長度! 計算的是內存地址的長度!
// 返回值: 如果返回值為0 代表連接成功!
// 返回值 != 0 ,代表連接失敗!
// 如果想要連接成功,必須實時監測服務器端的端口!
// 監測服務器端口: nc -lk 12345
int conn = connect(SocketNumber, (const struct sockaddr *)&serverAddress, sizeof(serverAddress));
4. 發送信息給服務器
// 參數1: 客戶端 Socket
// 參數2: void * 傳遞給服務器的數據! msg.UTF8String 就是直接將 OC 數據轉換成 C 語言的數據類型!
// 參數3: size_t 鎖傳遞給服務器數據的長度!
// 參數4: 傳0 等待服務器響應數據!
NSString *msg = @"hello socket";
send(SocketNumber, msg.UTF8String, strlen(msg.UTF8String), 0);
5.接受服務器返回的數據!
// 參數1:客戶端 Socket :服務器確定返回給哪一個客戶端數據.
// 參數2:void * :接收服務器返回數據的地址(區域)
// 參數3:size_t :接受地址的長度
// 參數4:傳0 等待服務器返回數據!
// 返回值: 就是服務器返回的數據長度!
ssize_t buffer[1024];
ssize_t length = recv(SocketNumber, buffer,sizeof(buffer), 0);
// 獲得服務器返回的數據(從 buffer 中取出需要的數據)
// 根據二進制數據,拼接字符串
// Bytes: 網絡中傳遞的數據流(比特流/字節)
NSString *returnMsg = [[NSString alloc] initWithBytes:buffer length:length encoding:NSUTF8StringEncoding];
6.一個請求結束之后(接收到響應之后),需要手動關閉Socket!
close(SocketNumber);