Socket: "主机" + "端口" = 套接字/插座; 仅仅是一个通信模型,不属于七层协议(网络协议).
一台电脑(IP)的一个应用程序(端口) 和 另一台电脑(IP)的应用程序(端口) 之间的通信就是通过两个socket进行连接
最常见的socket模型
一个 Socket 至少包含2层协议:网络层/传输层
TCP/IP ->socket TCP端口(传输层) IP主机(网络层)
UDP/IP ->socket UDP端口(传输层) IP主机(网络层)
思路:
1.创建一个 客户端Socket!
2.创建一个 服务器端Socket!
3.连接 两个Socket
4.客户端Socket发送聊天信息给服务器端Socket!
5.服务器端Socket接收到客户端Socket之后,返回信息给客户端Socket!
6.查看服务器端Socket传递回来的信息.
demo:
#import "ViewController.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
@interface ViewController ()
@end
// 在终端输入以下命令: nc -lk 12345(在终端中必须开启服务器,然后设置这个端口号才能运行成功)
// 在终端输入以下命令: nc -lk 12345(在终端中必须开启服务器,然后设置这个端口号才能运行成功)
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@"touchesBegan");
// 1. 创建客户端Socket!
// Socket 参数: Socket = TCP/IP
// 参数:
// 1. AF_INET/IPv4 AF_INET6/IPv6 协议域(IP/主机)
// 2. SOCK_STREAM/TCP SOCK_DGRAM/UDP
// 3. 传0,会根据第二个参数自动选择协议类型
// 返回值: 大于0,代表客户端Socket创建成功!
int SocketNumber = socket(AF_INET, SOCK_STREAM, 0);
if (SocketNumber > 0) {
NSLog(@"客户端Socket创建成功:%d",SocketNumber);
}
// 2. 创建服务器端Socket.
struct sockaddr_in serverAddress;
// 定义服务器端Socket的协议域(IPv4)
serverAddress.sin_family = AF_INET;
// 服务器端的IP地址!
// 本机IP地址:
// 127.0.0.1(所有的计算机都有的地址!指的就是主机本身)
// 192.168.44.72 (网关动态分配的IP地址,每天都可能改变!)
// localhost :指向的就是(127.0.0.1),本机域名!
// serverAddress.sin_addr.s_addr = inet_addr("192.168.44.75");
serverAddress.sin_addr.s_addr = inet_addr("192.168.39.26");
// 设置服务器端Socket的端口号: 1024~65535
serverAddress.sin_port = htons(12345);
// 3. 连接两个Socket!
// 参数:
// 1. 客户端Socket
// 2. 服务器端Socket地址
// 3. 长度(服务器端Socket(结构体)长度).
// sizeof 计算结构体地址长度!
// 返回值:返回值=0,代表连接成功!
int result = connect(SocketNumber, (const struct sockaddr *)&serverAddress, sizeof(serverAddress));
NSLog(@"result:%d",result);
// 要想保证连接成功,必须首先监测服务器端的端口号!
// 监测服务器端端口号: 12345
// 在终端输入以下命令: nc -lk 12345(在终端中必须开启服务器,然后设置这个端口号才能运行成功)
// 4. 客户端发送消息给服务器.
// 参数:
// 1.客户端Socket
// 2.客户端发送给服务器的内容
// 3.第二个参数的大小/长度
// 4.0,等待服务器返回内容!
// 注意: sizeof :计算的是地址长度,不是字符串长度!
// strlen:计算的是字符串的长度!
NSString *Msg = @"hello socket!";
send(SocketNumber, Msg.UTF8String, strlen(Msg.UTF8String), 0);
// 5.接收服务器端Socket返回的数据
// 参数:
// 1.客户端Socket
// 2.服务器返回的内容存放的位置.
// 3.第二个参数的长度!
// 4.传0,等待接收数据.
// 返回值: 长度.返回的数据的长度!
ssize_t buffer[1024];
ssize_t length = recv(SocketNumber, buffer, sizeof(buffer), 0);
// 从 buffer 中取出接收到的数据!
NSString *recMsg = [[NSString alloc] initWithBytes:buffer length:length encoding:NSUTF8StringEncoding];
NSLog(@"recMsg:%@",recMsg);
// AsyncSocket
}
@end