1 Socket基础
在IOS中,根据不同的语言环境可以使用不同的方法来创建socket连接。
1) 在Objective-C语言环境使用NSStream类API
*如果知道远程主机的DNS或者是IP地址,那么可以使用CFStreamCreatePairWithSocketToHost 或者函数 CFStreamCreatePairWithSocketToCFHost创建core foundation的连接,然后将CFStream对象toll-free bridged转换为NSStream 对象。*也可以传递给CFStreamCreatePairWithSocketToNetService函数一个CFNetServiceRef对象,来创建一个到Bonjour 服务器上的连接。
2) 在C语言环境使用CFStream类API
可以使用低级别的CFStream API来创建socket连接,这种方式与NSStream API的使用方式一样,也是通过三个函数来创建与远程主机的socket连接:CFStreamCreatePairWithSocketToHost 、CFStreamCreatePairWithSocketToCFHost或CFStreamCreatePairWithSocketToNetService。只是不需要将其转换为NSStream 对象,其使用方式与第1种类似。
3) 在跨平台环境使用POSIX调用
也可以使用POSIX类型的socket连接,但是如果在OS X 和iOS系统中,应避免使用这种方式,因为其使用方式非常繁琐。特别是不要在GUI主线程中使用同步方式的POSIX连接,因为这样会影响用户体验。
2 BSD Socket
2.1 简介
UNIX内核加入TCP/IP协议的时候,便在系统中引入了一种新的IO操作,只不过由于网络连接的不可靠性,所以网络IO比本地设备的IO复杂很多。这一系列的接口叫做BSD Socket API,当初由伯克利大学研发,最终成为网络开发接口的标准。 网络通信从本质上讲也是进程间通信,只是这两个进程一般在网络中不同计算机上。
由于本文重点是讨论IOS的socket编程,并且Apple官网也不推荐使用BSD socket编程,所以这里只稍微纪录,若需详细研究可以参考《UNIX网络编程卷1:套接字联网API(第3版)》和另一篇笔记《Socket知识整理》。
2.2 基本程序
socket连接由TCP和UDP两种类型,而TCP的使用频率较高,下面参考《UNIX网络编程卷1:套接字联网API(第3版)》的基本TCP连接图,实现一个简单的例子,其中这个例子是UNIX程序,即在MAC系统中也可正确执行。
图 21 基本TCP客户端/服务器socket连接图
2.2.1 Client端程序
2 #include <netinet/in.h>
3 #include <sys/socket.h>
4 #include <arpa/inet.h>
5 #include <string.h>
6
7 int main (int argc, const char * argv[])
8 {
9 struct sockaddr_in server_addr;
10 server_addr.sin_len = sizeof(struct sockaddr_in);
11 server_addr.sin_family = AF_INET;
12 server_addr.sin_port = htons(11332);
13 server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
14 bzero(&(server_addr.sin_zero),8);
15
16 int server_socket = socket(AF_INET, SOCK_STREAM, 0);
17 if (server_socket == -1) {
18 perror("socket error");
19 return 1;
20 }
21 char recv_msg[1024];
22 char reply_msg[1024];
23
24 if (connect(server_socket, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in))==0) {
25 //connect 成功之后,其实系统将你创建的socket绑定到一个系统分配的端口上,且其为全相关,包含服务器端的信息,可以用来和服务器端进行通信。
26 while (1) {
27 bzero(recv_msg, 1024);
28 bzero(reply_msg, 1024);
29 long byte_num = recv(server_socket,recv_msg,1024,0);
30 recv_msg[byte_num] = '