OC 30 day
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
創建時,看到系統提示要三個參數,但是實在是看不懂?
讓我們來google一下,剛好看到了這一篇翻轉工作室的文章
int scoket(int domain,int type,int protocol);
參數 domain 或稱為 family,是用來選擇使用哪一種通訊協定的家族系列,domain 可選擇下列之一:
其中『AF_』代表 Address Family,有些系統使用『PF_』(Protocol Family),兩者是相通的。domain 參數也如同 sockadd_in 資料結構中的 sin_family 參數一樣。
參數 type 是設定該 Socket 的類型,可選擇下列類型之一:
參數 protocol 是在某一個 domain 之下,選擇所要哪一種協定。例如選定 AF_INET domain 系列時,所使用的協定可以是 TCP、UDP 或 IP中的一種。但當設定 domain 和 type 值時,對於所使用的協定大多已經指定完成,因此 protocol 的值一般都設定為0。但有一特殊情況,如果 Socket 的型態是 SOCK_RAW 時,必須在參數中指定它的上層協定為 TCP、UDP、IP 或 ICMP。
注意
type 與 protocol不可以隨意組合,如SOCKET_STREAM不可以跟IPPROTO_UDP組合。當地三個參數為0時,會自動選擇地=個參數類型對應默認協議。
//第一個參數 domain 協議 指定IPv4
//第二個參數 type socket的類型 流socket 數據報socket
//第三個參數 protocol 協議
//返回值 如果創建成功返回的是socket的描述符,失敗-1
我們來實踐看看吧
//1. 創建Socket
//第一個參數 domain 協議 指定IPv4
//第二個參數 type socket的類型 流socket 數據報socket
//第三個參數 protocol 協議
//返回值 如果創建成功返回的是socket的描述符,失敗-1
int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect要三個參數,但是依然是看不懂?。
於是就交給google大神吧。
參數一:套接字描述符
參數二:指向數據結構sockaddr的指針,其中包含目的端口與IP位址
參數三:參數二socketaddr的長度,可以通過sizeof(struct sockaddr)獲得
返回值
成功則返回0,失敗返回非0; 錯誤碼 GetLastError()
EBADF 參數sockfd 非合法socket處理代碼
EFAULT 參數serv_addr指針指向無法存取的內存空間
ENOTSOCK參數sockfd為一 文件描述詞,非socket。
EISCONN 參數sockfd的socket已是連線狀態
ECONNREFUSED 連線要求被server端拒絕。
ETIMEDOUT 企圖連線的操作超過限定時間仍未有響應。
ENETUNREACH 無法傳送數據包至指定的主機。
EAFNOSUPPORT sockaddr結構的sa_family不正確。
EALREADY socket為不可阻斷且先前的連線操作還未完成。
我們來實踐看看吧
//2. 連接伺服器
//第一個參數 socket的描述符
//第二個參數 結構體 ip地址與端口
//第三個參數 結構體的長度 sizeof
//返回值 成功0 失敗非0
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(clientSocket, &addr, sizeof(addr));
[self setUpViews];
然後會跳出一個警告
表示type不匹配,所以我們要轉型
//2. 連接伺服器
//第一個參數 socket的描述符
//第二個參數 結構體 ip地址與端口
//第三個參數 結構體的長度 sizeof
//返回值 成功0 失敗非0
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(clientSocket, (const struct sockaddr *)&addr, sizeof(addr));
完整的代碼:
//1. 創建Socket
//第一個參數 domain 協議 指定IPv4
//第二個參數 type socket的類型 流socket 數據報socket
//第三個參數 protocol 協議
//返回值 如果創建成功返回的是socket的描述符,失敗-1
int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//2. 連接伺服器
//第一個參數 socket的描述符
//第二個參數 結構體 ip地址與端口
//第三個參數 結構體的長度 sizeof
//返回值 成功0 失敗非0
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(12345);
int result = connect(clientSocket, (const struct sockaddr *)&addr, sizeof(addr));
if (result == 0){
NSLog(@"成功");
}else{
NSLog(@"失敗");
}
接下來連接伺服器就可以運行囉。