iOS APP 开发 OC 第十一天,创建socket并连接服务器

tags: OC 30 day

1. 导入头文件

#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>

2. 创建 socket


创建时,看到系统提示要三个参数,但是实在是看不懂?
让我们来google一下,刚好看到了这一篇翻转工作室的文章

函数原型

int scoket(int domain,int type,int protocol); 

domain 参数

参数 domain 或称为 family,是用来选择使用哪一种通讯协定的家族系列,domain 可选择下列之一:

  1. AF_UNIX:Unix Internet Protocol。此通讯家族并不是真正的网路通讯协定,而是用来作 Unix 作业系统中,各程序(Process)之间的通讯使用。一般使用在回授(Loopback)传输提供者,而其应用在主机内程序之间的通讯。
  2. AF_INET:Internet Protocol。此为 TCP/IP 的 Internet 通讯协定,传输提供者可能是 TCP 或 UDP,也是本章讨论的重点。
  3. AF_NS:Xerox NS Protocol。此为 Xerox 公司发展的通讯协定。
  4. AF_IMPLINK:Interface Message Protocol。此为一种智慧型的分封交换节点协定,这些节点都是使用点对点的连接方式,一般使用在租用电话线路来作资料传输使用。(不在本章讨论范围)

其中『AF_』代表 Address Family,有些系统使用『PF_』(Protocol Family),两者是相通的。domain 参数也如同 sockadd_in 资料结构中的 sin_family 参数一样。

type 参数

参数 type 是设定该 Socket 的类型,可选择下列类型之一:

  1. SOCK_STREAM:Stream Socket。传输提供者提供一个虚拟电路服务(TCP)。
  2. SOCK_DGRAM:Datagram Socket。提供电报传输服务(UDP)。
  3. SOCK_RAW:Raw Socket。通讯协定型态在传输层之下,譬如,在 AF_INET(传输层为 TCP 或 UDP)模式,SOCK_RAW 的通讯协定可以是 IP(Internet Protocol)或 ICMP(Internet Control Message Protocol)。
  4. SOCK_SEQPACKET:Sequenced Packet Socket。提供虚拟电路(TCP)并附有维护讯息的功能。

protocol 参数

参数 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);

3. 连接服务器


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(@"失败");
    }
    

接下来连接服务器就可以运行罗。


<<:  iOS APP 开发 OC 第十一天,使用 typedef 简化 block

>>:  专案生命周期(Project Life Cycle)

JS 33 - 在触控装置侦测手势的滑动方向!

大家好! 今天我们要实作在触控装置中侦测手势的方向。 我们进入今天的主题吧! 备注:前几天和今天的范...

Day 13 - PHP SDK: 查询订单状态

昨天 Day 12 介绍了 Sinopac PHP SDK 关於建立订单的部分,接着今天要介绍的是查...

Day 29 - BFS

大家好,我是长风青云。今天是铁人赛的29天。这是我最後一个要讲的演算法喔。 如果明天的部分不想看不想...

Day30 - 终於完赛的心得感言

参赛动机 老实说,今年其实没有打算要参赛,打算装死度过 刚好身边有朋友要转职,鼓励对方说可以参加铁人...

Day 16 ( 中级 ) 水底探照灯

水底探照灯 教学原文参考:水底探照灯 这篇文章会介绍,如何在 Scratch 3 里使用舞台九倍大角...