网络三要素:IP,端口,协议(TCP/UDP)
TCP:安全传输控制协议(类似电话)
1、建立连接,形成传输数据的通道,效率会比较低。
2、通过三次握手连接,是可靠协议,安全。
3、传输数据大小不限制。
UDP:用户数据报协议(类似短信)
1、不需要建立连接,将数据及源和目的封装成数据包。
2、不管对方是否接收,只管发送,是不可靠协议
3、每个数据包限制64K之内。
4、速度快。
Socket是为网络服务提供的一种机制,在Unix中,网络既是Socket,并不局限TCP/UDP,Socket可以用于自定义协议,通信两端都是Socket。
一个端口可以监听多个请求,但同一时刻只能建立一个连接。
网络通信其实就是Socket间通信,数据在两个Socket间通过IO传输,Socket开始是C语言,是跨平台的。
下面是Socket的简单使用
终端输入命令"nc -lk 123456";表示监听端口123456的数据。
#import "ViewController.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
@interface ViewController ()
@property (nonatomic) int clientSocket;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self doConnection];
//HTTP协议 是服务器和客户端之间的约定
NSString *request = @"GET / HTTP/1.1\n"
"Host: 127.0.0.1\n";
[selfsendWithStr:request];
}
- (void)doConnection {
//1.创建
/*
参数:
domain 协议域,AF_INET -> IPV4
type Socket类型,SOCK_STREAM(TCP)/SOCK_DGRAM(UDP)
protocol IPPROTO_TCP,如果是0,会自动根据第二个参数,选择合适的协议
返回值:
socket
*/
intclientSocket = socket(AF_INET,SOCK_STREAM,0);
//2.连接
/*
参数:
1 客户端socket
2 指向数据结构sockaddr的指针,其中包括目的 端口和IP地址
3 结构体数据长度
返回值:
0表示成功;其他表示失败,返回响应的错误代码
*/
struct sockaddr_in serverAddr;
//协议域 IPV4
serverAddr.sin_family = AF_INET;
//端口
serverAddr.sin_port = htons(12345);
//IP地址
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
//在C语言中,经常传递一个数据的指针,还需要指定数据的长度
int connResult = connect(clientSocket, (const struct sockaddr *)&serverAddr,sizeof(serverAddr));
if(connResult ==0) {
NSLog(@"连接成功");
} else {
NSLog(@"连接失败");
return;
}
_clientSocket = clientSocket;
}
- (void)sendWithStr:(NSString*)msg {
//3.发送
/*
参数:
1 客户端socket
2 发送内容地址
3 发送内容长度
4 发送方式标志,一般为0
返回值:
如果成功,则返回发送的字节数,失败则返回SOCKET_ERROR
*/
// NSString *msg = @"小酒窝\n";//10个字节
ssize_tsendLen = send(self.clientSocket, msg.UTF8String,strlen(msg.UTF8String), 0);
NSLog(@"发送了 %ld 个字节", sendLen);
//4.读
/**
参数
1 客户端socket
2 接收内容缓冲区地址 提前准备
3 接收缓冲区长度
4 接收方式。0表示阻塞,必须等待服务器返回数据
返回值:
如果成功,则返回读入的字节数,失败返回SOCKET_ERROR
*/
uint8_t buffer[1024];//接收缓冲区
ssize_t recvLen = recv(self.clientSocket, buffer,sizeof(buffer),0);
NSLog(@"接收了 %ld 个字节", recvLen);
//获取服务器返回的数据
NSData *data = [NSData dataWithBytes:buffer length:recvLen];
//转成OC字符串
NSString *receive = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", receive);
//5.关闭
close(self.clientSocket);
}