zoukankan      html  css  js  c++  java
  • Socket

          在本地可以通过进程PID(progress id)来唯一标识一个进程,但是在网络中这是行不通的。其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。这样利用三元组(ip地址,协议,端口)就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。

    什么是Socket?fopen fwrite fread

      上面我们已经知道网络中的进程是通过socket来通信的,那什么是socket呢?socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。

    socket连接和http连接的区别

    网页都是http协议传输到浏览器, 而http是基于socket之上的。socket是一套完成tcp,udp协议的接口。

    HTTP协议:简单对象访问协议,对应于应用层  ,HTTP协议是基于TCP连接的

    tcp协议:    对应于传输层

    ip协议:     对应于网络层 TCP/IP是传输层协议,主要解决数据如何在网络中传输;而HTTP是应用层协议,主要解决如何包装数据。

    Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。

    http连接:http连接就是所谓的短连接,即客户端向服务器端发送一次请求,服务器端响应后连接即会断掉;

    socket连接:socket连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉

    TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,我们来看看这三次对话的简单过程:1.主机A向主机B发出连接请求数据包;2.主机B向主机A发送同意连接和要求同步(同步就是两台主机一个在发送,一个在接收,协调工作)的数据包;3.主机A再发出一个数据包确认主机B的要求同步:“我现在就发,你接着吧!”,这是第三次对话。三次“对话”的目的是使数据包的发送和接收同步,经过三次“对话”之后,主机A才向主机B正式发送数据。 

    UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!  UDP适用于一次只传送大量数据、对可靠性要求不高的应用环境。 

    tcp协议和udp协议的差别 

    是否连接          面向连接                 面向非连接 

    传输可靠性       可靠                       不可靠 

    应用场合         传输少量数据         大量数据 

    速度                   慢                            快

    socket中TCP的三次握手建立连接详解

           我们知道tcp建立连接要进行“三次握手”,即交换三个分组。大致流程如下:

    • 客户端向服务器发送一个SYN J
    • 服务器向客户端响应一个SYN K,并对SYN J进行确认ACK J+1
    • 客户端再想服务器发一个确认ACK K+1

    只有就完了三次握手,但是这个三次握手发生在socket的那几个函数中呢?请看下图:

    201012122157476286.png

    图1、socket中发送的TCP三次握手

    从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。

    总结:客户端的connect在三次握手的第二个次返回,而服务器端的accept在三次握手的第三次返回。

    socket中TCP的四次握手释放连接详解

           上面介绍了socket中TCP的三次握手建立过程,及其涉及的socket函数。现在我们介绍socket中的四次握手释放连接的过程,请看下图:

    201012122157494693.png

    图2、socket中发送的TCP四次握手

    图示过程如下:

    • 某个应用进程首先调用close主动关闭连接,这时TCP发送一个FIN M;
    • 另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。它的接收也作为文件结束符传递给应用进程,因为FIN的接收意味着应用进程在相应的连接上再也接收不到额外数据;
    • 一段时间之后,接收到文件结束符的应用进程调用close关闭它的socket。这导致它的TCP也发送一个FIN N;
    • 接收到这个FIN的源发送端TCP对它进行确认。

    这样每个方向上都有一个FIN和ACK。

    一.什么是Socket

    socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。我的理解就是Socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。

    二.OSI七层协议与TCP/IP四层协议

    Pasted Graphic.tiff

    Pasted Graphic 1.tiff

    三.TCPSocket的使用

    1.TCP客户端的写法

    1).创建客户端套接字对象

        _clientSocket = [[AsyncSocket alloc]initWithDelegate:self];

    建立与服务器的链接

        [_clientSocket connectToHost:@"192.168.1.1" onPort:5555 error:nil];

    客户端监听

        [_clientSocket readDataWithTimeout:-1 tag:100];

    2)客户端代理

    建立与服务器的连接

    - (BOOL)onSocketWillConnect:(AsyncSocket *)sock

    连接服务器成功

    - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port

    [sock writeData:[@"登录请求" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:100];

    向服务器发送数据成功

    - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag

    收到来自服务器的消息

    - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

    断开连接

    - (void)onSocketDidDisconnect:(AsyncSocket *)sock

    2.TCP服务端的写法

    1).创建服务端套接字对象

    _serverSocket = [[AsyncSocket alloc]initWithDelegate:self];

    if ([_serverSocket acceptOnPort:5555 error:nil])

        {

            NSLog(@"服务器启动了");

        }else

        {

            NSLog(@"服务器启动失败");

        }

    2).服务端代理

    收到了来自客户端的TCP连接请求

    - (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket

    [newSocket writeData:[@"蓝翔技校欢迎你..." dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:100];

        //保存客户端

        _clientSocket = newSocket;

    收到了来自客户端的数据

    - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

    NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

    服务端发送消息成功

    - (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag

    //继续监听客户端数据

         [_clientSocket readDataWithTimeout:-1 tag:100];

    四.UDPSocket的使用

    1.创建UDP套接字对象

    _recevSocket = [[AsyncUdpSocket alloc]initWithDelegate:self];

           _sendSocket = [[AsyncUdpSocket alloc]initWithDelegate:self];

        

          [_recevSocket bindToPort:0x1234 error:nil];

              [_sendSocket bindToPort:0x4321 error:nil];

        

          //监听

          [_recevSocket receiveWithTimeout:-1 tag:100];

    2.UDPSokect代理

    收到了对方传过来的消息

    - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port

    [_recevSocket receiveWithTimeout:-1 tag:100];

    发送消息成功

    - (void)onUdpSocket:(AsyncUdpSocket *)sock didSendDataWithTag:(long)tag

    3.UDPSoket发送消息

    [_sendSocket sendData:[contentField.text dataUsingEncoding:NSUTF8StringEncoding] toHost:ipField.text port:0x1234 withTimeout:-1 tag:200];

  • 相关阅读:
    Linux 分区注意事项
    wamp2.4-- 为WAMP中的mysql设置密码密码
    转multicast vs broadcast
    转 生成 HTMLTestRunner 测试报告
    Eclipse和PyDev搭建完美Python开发环境(Windows篇)
    转 深入解析浏览器的幕后工作原理
    selenium + python 怎样才能滚到页面的底部?
    Java ZIP压缩和解压缩文件(解决中文文件名乱码问题)
    Java中使用poi导入、导出Excel
    eclipse下的tomcat内存设置大小
  • 原文地址:https://www.cnblogs.com/PengFei-N/p/4703256.html
Copyright © 2011-2022 走看看