OSI七层网络模型:
1.物理层:二进制转换成电流,电流转换成二进制,中继器放大电信号, 最小传输单位-----位(比特流),定义物流设备标准,如网线接口类型,传输介质速率.
2.数据链路层:对比特流的包装,检测保证数据传输的可靠性,对mac地址的解封装,交换机处在者一层,最小传输单位----帧.
MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址、硬件地址,用来定义网络设备的位置。在OSI模型中,第三层网络层负责 IP地址,第二层数据链路层则负责 MAC地址。因此一个主机会有一个MAC地址,而每个网络位置会有一个专属于它的IP地址。MAC地址是网卡决定的,是固定的。用来表示互联网上每一个站点的标识符,采用十六进制数表示,共六个字节(48位)。其中,前三个字节是由IEEE的注册管理机构RA负责给不同厂家分配的代码(高位24位),也称为“编制上唯一的标识符”(Organizationally Unique Identifier),后三个字节(低位24位)由各厂家自行指派给生产的适配器接口,称为扩展标识符(唯一性)。一个地址块可以生成224个不同的地址。MAC地址实际上就是适配器地址或适配器标识符EUI-48。
3.网络层:位于地理位置不同的网络中的两个主机系统之间提供链接和路径选择,路由器在这一层,寻找iP地址,最小单位----分组(包);这一层会有网络阻塞(处理数据需要时间,耽误这些时间,其他数据需要等待产生阻塞);
网关:网间连接器,协议转换器,网关在网络层上实现网络互连,对接收到的信心重新打包,以适应目的系统的需求;
网关实质上是一个网络通向其他网络的IP地址;只有通过网关才能找到对应的IP,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通信,网关的IP地址是具有路由功能的设备的IP地址,具有路由功能的设备有路由器、启用了路由协议的服务器(实质上相当于一台路由器)、代理服务器(也相当于一台路由器)。
解决阻塞的办法:数据分组,编号传输出去;然后接收到数据后排序重组解码;选择最优路径;丢包也是发生在网络层.
4.传输层:定义传输数据的协议和端口号(TCP/IP参考模型),每个服务占一个端口号;tcp三次握手建立数据传输通道;通道两端都会有socket;
5.会话层:数据的收发;最小单位---spdu;
6.表示层:确保一个系统的应用层发送的消息可以被另一个系统的应用层读取,编码转换,数据解析; 最小单位----ppdu;
7.应用层:为操作系统或网络应用程序提供访问网络服务的接口,应用层协议包括:telnet(Internet远程登录服务的标准协议和主要方式),FTP(文件传输协议),http(超文本传输协议),snmp简单网络管理协议,DNS;最小单位---apdu;
应用层为操作系统或网络应用程序提供访问网络服务的接口。
应用层协议的代表包括:
Telnet
(
Internet
远程登录服务的标准
协议和主要方式)、
FTP
(文件传输协议)、
HTTP
(超文本传送协
议)、
SNMP
(简单网络管理协议)等。
8.socket俗称套接字,本人理解为通信的两端,应用程序通过socket向网络发送请求或向网络做出应答,网路通信的实质就是数据在两个socket之间通过输入输出流传输数据,是socket位于 传输层和应用层之间;
网络参考模型
消息发送
iP和端口
TCP和UDP
TCP的三次握手:
对英文字母缩写的总结:Seq 是 Sequence 的缩写,表示序列;Ack(ACK) 是 Acknowledge 的缩写,表示确认;SYN 是 Synchronous 的缩写,愿意是“同步的”,这里表示建立同步连接;FIN 是 Finish 的缩写,表示完成。
CLOSED
状态;服务器端调用 listen() 函数后,套接字进入
LISTEN
状态,开始监听客户端请求。
SYN-SEND
状态。
SYN-RECV
状态。
ESTABLISED
状态,表示连接已经成功建立。
ESTABLISED
状态。
ESTABLISED
状态,连接建立成功,接下来就可以收发数据了。
Ack = Seq + 1
是否成立,如果成立说明对方正确收到了自己的数据包。
socket通信图
========================
socket是纯c语言的,是跨平台的.
socket一般通信步骤
//1.创建socket
/*
int socket(int domain, int type, int protocol);
1.协议族 ipv4或者其他的ip协议.
2.type 指定传输层使用TCP或者 UDP (TCP SOCK_STREAM流) (UDP SOCK_DGRAM数据报文)
3.protocol指定传输层使用的协议
返回值 大于0 创建socket成功
*/
int clientSocket =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
NSLog(@"%d",clientSocket);
//2.建立连接
/*
1.socket
2.const struct sockaddr * 指定对方服务器的ip地址和端口号等信息结构体
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr = inet_addr(SERVER_IP);
sockaddr_in 比 sockaddr更加容易看的明白,可以类型转换
3.结构体的字节长度
返回值: 0 成功 非0 失败
*/
struct sockaddr_in addr;
//指定协议族 ipv4
addr.sin_family = AF_INET;
//端口号,htons高地位转换
addr.sin_port = htons(12345);
//12345-->0x3039-->0x3930-->14640
// NSLog(@"%d",htons(12345));
//指定IP地址,inet_addr把字符串转换成网络地址(数字)
addr.sin_addr.s_addr =inet_addr("127.0.0.1");
int connResult = connect(clientSocket, (const struct sockaddr *)&addr, sizeof(addr));
//本地开启服务器终端 (netcat) nc -lk 12345
if(connResult == 0){
NSLog(@"ok");
}else{
NSLog(@"fail");
}
//3.发送数据给服务器
/*
1.socket
2.要发送的数据
3.要发送数据的字节长度
4.调用执行方式 flag是否阻塞,一般填0即可
返回值:成功发送的字节数
*/
char * str = "itcast";
ssize_t sentLen = send(clientSocket, str, strlen(str), 0);
//sizeof表示在内存中保存该变量需要多少字节 ,一个字节8位
// NSLog(@"%zd %lu %lu",sentLen,strlen(str),sizeof(str));
//4.接受数据(从服务器接收数据)
/*
1.socket
2.用于保存数据的缓存
3.缓冲区的长度
4.指定调用方式。一般填0即可
返回值接收的字节长度
*/
char *buffer[1024];
ssize_t recvLen = recv(clientSocket, buffer, sizeof(buffer),0);
// NSLog(@"---->%zd",recvLen);
//输出字符串
//二进制 NSData
NSData *data = [NSDatadataWithBytes:bufferlength:recvLen];
//字符串输出
NSString *string = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
NSLog(@"%@",string);
//5.关闭数据
//socket
close(clientSocket);
/*
1.考代码
2.连接到百度服务器
3.发送http请求
4.得到完整的响应
----截取响应体
5.显示到界面
*/
#import "ViewController.h"
#import
#import
#import
@interface ViewController ()
@property (weak, nonatomic) IBOutletUIWebView *webview;
@property(nonatomic,assign)int clientSocket;
@end
@implementation ViewController
- (void)viewDidLoad {
[superviewDidLoad];
//2.连接到百度服务器治理不是填域名,填ip地址 ping www.baidu.com
//119.75.217.109 80
BOOL connResult = [selfcreateAndConnWithIPaddress:@"119.75.217.109"port:80];
if(connResult){
// NSLog(@"ok");
}else{
// NSLog(@"fail");
}
//3.发送http请求,监控浏览器发出的请求
//拼接请求
NSString *requestString = @"GET / HTTP/1.1\r\n"
"Host: www.baidu.com\r\n"
"User-Agent: Android\r\n"
"Connection: close\r\n\r\n";
//keep-alive close
/*
Connection : keep-alive 长连接,等一段时间没有请求,释放连接.
Connection : close 短连接 每次得到响应就释放连接.
*/
//返回完整的响应,包含状态行,响应头,响应体
NSString *responseString = [selfsendAndRecv:requestString];
//截取响应体,截取依据空行
NSRange range = [responseString rangeOfString:@"\r\n\r\n"];
NSString *responseString2 = [responseStringsubstringFromIndex:range.location+range.length];
NSLog(@"%@",responseString2);
[self.webviewloadHTMLString:responseString2baseURL:[NSURLURLWithString:@"http://www.baidu.com"]];
}
//创建socket并连接服务器
-(BOOL)createAndConnWithIPaddress:(NSString *)ipaddress port:(int)port{
self.clientSocket =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr =inet_addr(ipaddress.UTF8String);
int connResult = connect(self.clientSocket, (conststructsockaddr *)&addr,sizeof(addr));
if(connResult == 0){
return YES;
}else{
return NO;
}
}
//发送数据并接受服务器返回的数据
-(NSString *)sendAndRecv:(NSString *)message{
char * str = message.UTF8String;
ssize_t sentLen = send(self.clientSocket, str,strlen(str),0);
//大集合,用户组装每次接受的数据
NSMutableData *mData = [NSMutableDatadata];
char *buffer[1024];
ssize_t recvLen = recv(self.clientSocket, buffer,sizeof(buffer),0);
[mData appendBytes:buffer length:recvLen];
while (recvLen != 0) {
//不断的去取数据
recvLen = recv(self.clientSocket, buffer,sizeof(buffer),0);
[mData appendBytes:buffer length:recvLen];
}
//字符串输出
NSString *string = [[NSStringalloc]initWithData:mData.copyencoding:NSUTF8StringEncoding];
return string;
}
@end
/*
1.界面搭建
2.考代码
---创建socket并连接服务器
---发送
*/
#import "ViewController.h"
#import
#import
#import
@interface ViewController ()
@property (weak, nonatomic) IBOutletUITextField *tf_ipaddress;
@property (weak, nonatomic) IBOutletUITextField *tf_port;
@property (weak, nonatomic) IBOutletUITextField *tf_message;
@property (weak, nonatomic) IBOutletUITextView *tv_showMessage;
@property(nonatomic,assign)int clientSocket;
@end
@implementation ViewController
//发送
- (IBAction)sendClick:(id)sender {
NSString *recvMsg = [selfsendAndRecv:self.tf_message.text];
self.tv_showMessage.text = recvMsg;
}
//连接
- (IBAction)connClick:(id)sender {
NSString *ipaddresss = self.tf_ipaddress.text;
int port = [self.tf_port.textintValue];
BOOL connResult = [selfcreateAndConnWithIPaddress:ipaddresssport:port];
if(connResult){
NSLog(@"ok");
}else{
NSLog(@"fail");
}
}
//创建socket并连接服务器
-(BOOL)createAndConnWithIPaddress:(NSString *)ipaddress port:(int)port{
self.clientSocket =socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr =inet_addr(ipaddress.UTF8String);
int connResult = connect(self.clientSocket, (conststructsockaddr *)&addr,sizeof(addr));
if(connResult == 0){
return YES;
}else{
return NO;
}
}
//发送数据并接受服务器返回的数据
-(NSString *)sendAndRecv:(NSString *)message{
char * str = message.UTF8String;
ssize_t sentLen = send(self.clientSocket, str,strlen(str),0);
char *buffer[1024];
ssize_t recvLen = recv(self.clientSocket, buffer,sizeof(buffer),0);
NSData *data = [NSDatadataWithBytes:bufferlength:recvLen];
//字符串输出
NSString *string = [[NSStringalloc]initWithData:dataencoding:NSUTF8StringEncoding];
// NSLog(@"%@",string);
return string;
}
@end