Socket
又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,Socket
是纯C语言的,是 HTTP
协议的底层。
Socket 的通信过程
- 创建
Socket
- 连接到服务器
- 发送数据到服务器
- 从服务器接受数据
- 关闭连接
Socket 的简单使用过程
首先,使用 Socket
需要导入以下头文件
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
复制代码
创建 Socket
第一步,创建 Socket
,创建的函数为
int socket(int, int, int);
复制代码
三个参数分别为 domain
协议簇,指定 Socket
类型以及指定 protocol
协议。
-
常用的
domain
协议族有AF_INET
、AF_INET6
分别代表IPV4
和IPV6
。 -
常用的
Socket
类型有SOCK_STREAM
和SOCK_DGRAM
分别代表流式和数据报式。 -
协议使用 TCP协议 即填入
IPPROTO_TCP
,也可以只填 0 ,它可以根据前两个参数自动获取。
函数返回一个 int
类型数据,代表 socket
的描述符,即其本身,如果失败则返回 INVALID_SOCKET
。
eg.
int clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
复制代码
连接到服务器
第二步,连接到服务器的函数为:
int connect(int, const struct sockaddr *, socklen_t);
复制代码
第一个参数需要填入创建的 socket
,第二个参数为 sockaddr
结构指针,该结构中包含了要结合的地址和端口号,第三个参数为结构体的 size
。
以下是创建 sockaddr 结构体指针的过程:
struct sockaddr_in addr;
addr.sin_family = AF_INET; // 指定协议簇
addr.sin_port = htons(12345); // 指定端口号
addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 指定地址
复制代码
当函数调用成功则返回 0 ,失败则返回对应的错误数值。
eg.
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 这里要求的是一个常量地址所以进行了强转
int result = connect(clientSocket, (const struct sockaddr*)&addr, sizeof(addr));
if (result!=0) {
NSLog(@"失败");
return;
}
NSLog(@"成功");
复制代码
我们可以使用终端输入 nc -lk 12345
创建对应服务器,这样就可以与客户端进行互动。
发送到服务器
第三步发送数据到服务器调用函数:
ssize_t send(int, const void *, size_t, int);
复制代码
第一个参数为 socket
描述符,第二个参数为一个任意常量,第三个参数为常量的长度,第四个参数为是否阻塞,一般填 0 ,函数返回发送数据的 size
。
eg.
const char *msg = "这是一段话";
ssize_t count = send(clientSocket, msg, strlen(msg), 0);
复制代码
我们可以看到运行后在终端中以及显示了对应的文字。
从服务器接收
接收与发送的方法类似:
ssize_t recv(int, void *, size_t, int);
复制代码
第一个参数为 socket
描述符,第二个参数为用于接收数据的缓冲区,第三个参数为缓冲区的 size
,第四个参数一般填 0,函数返回真正接收的数据长度。
我们需要先定义一个缓冲区用于接受参数,然后调用函数获取数据。
uint8_t buffur[1024];
ssize_t recvCount = recv(clientSocket, buffur, sizeof(buffur), 0);
复制代码
获取数据以后还需要将其合并并转换为 OC 字符串。
// 使用 NSData 将其转换为 data 数据
NSData *data = [NSData dataWithBytes:buffur length:recvCount];
// 再将 NSData 类型转换为 NSString
NSString *str = [[NSString alloc]initWithData:data encoding:kCFStringEncodingUTF8];
NSLog(@"%@",str);
复制代码
运行后只要在终端中输入内容即可在控制台中输出。
关闭
close(clientSocket);
复制代码
即可。