HTTP 以及 TCP/IP、Socket 简介

首先我们要知道的是,Socket是对TCP/IP协议封装的一个调用接口(API),通过Socket,我们可以使用TCP/IP协议。本文主要介绍 TCP/IP 协议、Socket原理以及Socket在iOS开发过程中的使用

为了更深刻的理解Socket,我们先详细了解一下什么是TCP/IP协议:

一、TCP/IP协议介绍

TCP/IP协议是一个协议簇。里面包括很多协议的。UDP只是其中的一个。之所以命名为TCP/IP协议,因为TCP,IP协议是两个很重要的协议,就用他两命名了。TCP/IP协议集包括网络接口层、网络层、传输层、应用层。

1.1、网络接口层

网络接口层又称作主机到网络层(host-to-network),网络接口层的功能包括IP地址与物理地址硬件的映射,以及将IP封装成帧,基于不同硬件类型的网络接口,网络访问层定义了和物理介质的连接。

物理层是定义物理介质的各种特性:机械特性、电子特性、功能特性、规程特性。

数据链路层是负责接收IP数据包并通过网络发送,或者从网络上接收物理帧,抽出IP数据包,交给IP层。

ARP是正向地址解析协议,通过已知的IP,寻找对应主机的MAC地址。
RARP是反向地址解析协议,通过MAC地址确定IP地址。比如无盘工作站还有DHCP服务。

常见的接口层协议有:Ethernet 802.3、Token Ring 802.5、X.25、Frame relay、HDLC、PPP ATM等。

1.2、网络层

网络层负责相邻计算机之间的通信。其功能包括三方面。

1、处理来自传输层的分组发送请求,收到请求后,将分组装入IP数据报,填充报头,选择去往信宿机的路径,然后将数据报发往适当的网络接口。

2、处理输入数据报:首先检查其合法性,然后进行寻径--假如该数据报已到达信宿机,则去掉报头,将剩下部分交给适当的传输协议;假如该数据报尚未到达信宿,则转发该数据报。

3、处理路径、流控、拥塞等问题。

网络层包括:IP(Internet Protocol)协议、ICMP(Internet Control Message Protocol)控制报文协议、ARP(Address Resolution Protocol)地址转换协议、RARP(Reverse ARP)反向地址转换协议。

IP是网络层的核心,通过路由选择将下一条IP封装后交给接口层。IP数据报是无连接服务。
ICMP是网络层的补充,可以回送报文。用来检测网络是否通畅。

Ping命令就是发送ICMP的echo包,通过回送的echo relay进行网络测试。

1.3、传输层

传输层提供应用程序间的通信。其功能包括:格式化信息流、提供可靠传输。

传输层协议主要是:传输控制协议TCP(Transmission Control Protocol)和用户数据报协议UDP(User Datagram protocol)。

TCP的一些基本知识包括:三次握手和四次断开,TCP这种使用面向连接的通信方式,大大提高了数据通信的可靠性,使发送数据端和接收端在数据正式传输前就有了交互,为数据正式传输打下了可靠的基础

下面分别简单介绍一下TCP的三次握手、四次断开和UDP:

1.3.1、TCP三次握手过程以及特点

三次握手过程:

1 主机A通过向主机B 发送一个含有同步序列号的标志位的数据段给主机B ,向主机B 请求建立连接,通过这个数据段,主机A告诉主机B两件事:我想要和你通信;你可以用哪个序列号作为起始数据段来回应我.

2 主机B 收到主机A的请求后,用一个带有确认应答(ACK)和同步序列号(SYN)标志位的数据段响应主机A,也告诉主机A两件事:我已经收到你的请求了,你可以传输数据了;你要用哪佧序列号作为起始数据段来回应我

3 主机A收到这个数据段后,再发送一个确认应答,确认已收到主机B 的数据段:"我已收到回复,我现在要开始传输实际数据了

这样3次握手就完成了,主机A和主机B 就可以传输数据了.

三次握手的特点:

1、没有应用层的数据
2、SYN这个标志位只有在TCP建产连接时才会被置1
3、握手完成后SYN标志位被置0

1.3.2、TCP四次断开过程

1、当主机A完成数据传输后,将控制位FIN置1,提出停止TCP连接的请求

2、主机B收到FIN后对其作出响应,确认这一方向上的TCP连接将关闭,将ACK置1

3、由B 端再提出反方向的关闭请求,将FIN置1

4、主机A对主机B的请求进行确认,将ACK置1,双方向的关闭结束.

ACK :TCP报头的控制位之一,对数据进行确认.确认由目的端发出,用它来告诉发送端这个序列号之前的数据段都收到了.比如,确认号为X,则表示前X-1个数据段都收到了,只有当ACK=1时,确认号才有效,当ACK=0时,确认号无效,这时会要求重传数据,保证数据的完整性.

SYN :同步序列号,TCP建立连接时将这个位置1

FIN :发送端完成发送任务位,当TCP完成数据传输需要断开时,提出断开连接的一方将这位置1

1.3.3、UDP(User Data Protocol,用户数据报协议)

1、 UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段。

2、 由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

3、UDP信息包的标题很短,只有8个字节,相对于TCP的20个字节信息包的额外开销很小。

4、吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

5、UDP使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态表(这里面有许多参数)。

6、UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小。

我们经常使用“ping”命令来测试两台主机之间TCP/IP通信是否正常,其实“ping”命令的原理就是向对方主机发送UDP数据包,然后对方主机确认收到数据包,如果数据包是否到达的消息及时反馈回来,那么网络就是通的。

1.4、应用层

应用层向用户提供一组常用的应用程序,比如电子邮件、文件传输访问、远程登录等。远程登录TELNET使用TELNET协议提供在网络其它主机上注册的接口。TELNET会话提供了基于字符的虚拟终端。文件传输访问FTP使用FTP协议来提供网络内机器间的文件拷贝功能。

应用层协议主要包括如下几个:FTP、TELNET、DNS、SMTP、NFS、HTTP。

FTP(File Transfer Protocol)是文件传输协议,一般上传下载用FTP服务,数据端口是20H,控制端口是21H。
Telnet服务是用户远程登录服务,使用23H端口,使用明码传送,保密性差、简单方便。
DNS(Domain Name Service)是域名解析服务,提供域名到IP地址之间的转换,使用端口53。
SMTP(Simple Mail Transfer Protocol)是简单邮件传输协议,用来控制信件的发送、中转,使用端口25。
NFS(Network File System)是网络文件系统,用于网络中不同主机间的文件共享。
HTTP(Hypertext Transfer Protocol)是超文本传输协议,用于实现互联网中的WWW服务,使用端口80。

1.4.1、HTTP连接

HTTP协议即超文本传送协议(HypertextTransferProtocol )是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用。

HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。

1、在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。

2、在HTTP 1.1中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。

由于HTTP在每次请求结束后都会主动释放连接,因此HTTP连接是一种“短连接”,要保持客户端程序的在线状态,需要不断地向服务器发起连接请求。通常的

做法是即时不需要获得任何数据,客户端也保持每隔一段固定的时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表明知道客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”,若客户端长时间无法收到服务器的回复,则认为网络已经断开。

二、SOCKET原理介绍

2.1、套接字(socket)概念

套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

2.2 、建立socket连接

建立Socket连接至少需要一对套接字,其中一个运行于客户端,称为ClientSocket,另一个运行于服务器端,称为ServerSocket。

套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。

服务器监听:服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。

客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。

连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

2.3、SOCKET连接与TCP连接

创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。

2.4、Socket连接与HTTP连接

由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。

而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。

很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;

若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

三、Socket在iOS开发过程中的使用

下面简单介绍一下在iOS开发中,分别按照连接服务器、向服务器发送数据、接收服务器数据、输入输出流的监听四部分来示例介绍:

3.1、连接服务器

- (void)connectToHost 
{
    //1.建立连接
    NSString *host =@"127.0.0.1";
    intport =12345;

    //定义C语言输入输出流
    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;

    CFStreamCreatePairWithSocketToHost(NULL, (__bridge CFStringRef)host, port, &readStream, &writeStream);

    //把C语言的输入输出流转化成OC对象
    _inputStream = (__bridge NSInputStream *)(readStream);
    _outputStream = (__bridge NSOutputStream *)(writeStream);
    
    //设置代理
    _inputStream.delegate=self;
    _outputStream.delegate=self;

    //把输入输入流添加到主运行循环
    //不添加主运行循环 代理有可能不工作

    [_inputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    [_outputStream scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

    //打开输入输出流
    [_inputStream open];
    [_outputStream open];
}

3.2、向服务器发送数据

- (void)sendData
{
    // 把Str转成NSData
    NSData *data =[loginStr dataUsingEncoding:NSUTF8StringEncoding];
    [_outputStream write:data.bytes maxLength:data.length];
}

3.3、读取服务器数据

- (void)readServerData
{
    //建立一个缓冲区 可以放1024个字节
    uint8_t buf[1024];

    //返回实际装的字节数
    NSInteger len = [_inputStream read:buf maxLength:sizeof(buf)];

    //把字节数组转化成字符串
    NSData *data =[NSData dataWithBytes:buf length:len];

    //从服务器接收到的数据
    NSString *recStr =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    NSLog(@"%@",recStr);
}

3.4、遵守代理,监听输入输出流

-(void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
	NSLog(@"%@",[NSThread currentThread]);

	//NSStreamEventOpenCompleted = 1UL << 0,//输入输出流打开完成
	//NSStreamEventHasBytesAvailable = 1UL << 1,//有字节可读
	//NSStreamEventHasSpaceAvailable = 1UL << 2,//可以发放字节
	//NSStreamEventErrorOccurred = 1UL << 3,//连接出现错误
	//NSStreamEventEndEncountered = 1UL << 4//连接结束

	switch(eventCode) {
	    caseNSStreamEventOpenCompleted:
	    
	    NSLog(@"输入输出流打开完成");
	    break;

	    caseNSStreamEventHasBytesAvailable:
	    NSLog(@"有字节可读");

	    [self readServerData];
	    break;

	    caseNSStreamEventHasSpaceAvailable:

	    NSLog(@"可以发送字节");

	    break;

	    caseNSStreamEventErrorOccurred:
    
	    NSLog(@"连接出现错误");

	    break;

	    caseNSStreamEventEndEncountered:
    
	    NSLog(@"连接结束");

	    //关闭输入输出流

	    [_inputStream close];
	    [_outputStream close];

	    //从主运行循环移除

	    [_inputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
	    [_outputStream removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
	    break;

	    default:
	    break;

	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值