zoukankan      html  css  js  c++  java
  • socket编程及tcp、UDP协议

    1、TCP UDP区别:

      TCP有点:可靠,稳定,TCP可靠提现在TCP在传递数据之前,会有三次握手来建立连接,而且在数据传输时,有确认、窗口、重传、拥塞控制机制,在数据传完后,还会断开连接来节约系统资源。

      TCP缺点:慢、效率低、占用系统资源高,易呗攻击,TCP在传递数据之前,要先建立连接,这会消耗时间,而且在数据传输时,确认机制、重传机制、拥塞机制等都会消耗大量的时间,而且要再每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU,内存等硬件资源,而且,因为TCP有确认机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。

      UDP优点:快,比TCP稍安全,没有TCP的握手、确认、窗口、重传、拥塞控制等机制,UDP是一个无状态的传输协议,所以在传递数据时非常快,没有TCP的这些机制,UDP较TCP被攻击者利用的漏洞就要少一点。但UDP也是无法避免攻击的,比如UDP Flood攻击。。。

      UDP缺点:不可靠,不稳定 因为UDP没有TCP那些可靠的机制,在数据传递时,如果网络质量不好,就会容易丢包。

      TCP UDP
    是否连接 面向连接(TCP三次握手) 面向非连接
    传输可靠性 可靠 不可靠
    应用场合 少量数据,安全(浏览器HTTP、FTP Outlook、SMTP Putty) 传输大量数据(QQ语音、视频、直播等)
    速度

    2、TCP三次握手和四次挥手

      三次握手:

    初始状态:客户端A和服务器B均处于CLOSED状态,然后服务器B创建socket,调用监听接口使得服务器处于LISTEN状态,等待客户端连接。(后续内容用A,B简称代替)
    
    A首先向B发起连接,这时TCP头部中的SYN标识位值为1,然后选定一个初始序号seq=x(一般是随机的),消息发送后,A进入SYN_SENT状态,SYN=1的报文段不能携带数据,但要消耗一个序号。
    
    B收到A的连接请求后,同意建立连接,向A发送确认数据,这时TCP头部中的SYN和ACK标识位值均为1,确认序号为ack=x+1,然后选定自己的初始序号seq=y(一般是随机的),确认消息发送后,B进入SYN_RCVD状态,与连接消息一样,这条消息也不能携带数据,同时消耗一个序号。
    
    A收到B的确认消息后,需要给B回复确认数据,这时TCP头部中的ACK标识位值为1,确认序号是ack=y+1,自己的序号在连接请求的序号上加1,也就是seq=x+1,此时A进入ESTABLISHED状态,当B收到A的确认回复后,B也进入ESTABLISHED状态,至此TCP成功建立连接,A和B之间就可以通过这个连接互相发送数据了。

      四次挥手:

      

    初始状态:客户端A和服务器B之间已经建立了TCP连接,并且数据发送完成,打算断开连接,此时客户端A和服务器B是等价的,双方都可以发送断开请求,下面以客户端A主动发起断开请求为例。(后续内容用A,B简称代替)
    
    A首先向B发送断开连接消息,这时TCP头部中的FIN标识位值为1,序号是seq=m,m为A前面正常发送数据最后一个字节序号加1得到的,消息发送后A进入FNI_WAIT_1状态,FIN=1的报文段不能携带数据,但要消耗一个序号。
    
    B收到A的断开连接请求需要发出确认消息,这时TCP头部中的ACK标识位值为1,确认号为ack=m+1,而自己的序号为seq=n,n为B前面正常发送数据最后一个字节序号加1得到的,然后B进入CLOSE_WAIT状态,此时就关闭了A到B的连接,A无法再给B发数据,但是B仍然可以给A发数据(此处存疑),同时B端通知上方应用层,处理完成后被动关闭连接。然后A收到B的确认信息后,就进入了FIN_WAIT_2状态。
    
    B端应用层处理完数据后,通知关闭连接,B向A发送关闭连接的消息,这时TCP头部中的FIN和ACK标识位值均为1,确认号ack=m+1,自己的序号为seq=k,(B发出确认消息后有发送了一段数据,此处存疑),消息发送后B进入LACK_ACK状态。
    
    A收到B的断开连接的消息后,需要发送确认消息,这是这时TCP头部中的ACK标识位值为1,确认号ack=k+1,序号为m+1(因为A向B发送断开连接的消息时消耗了一个消息号),然后A进入TIME_WAIT状态,若等待时间经过2MSL后,没有收到B的重传请求,则表明B收到了自己的确认,A进入CLOSED状态,B收到A的确认消息后则直接进入CLOSED状态。至此TCP成功断开连接。

    3、socket理解:

    socket本质是编程接口(API),对TCP/IP的封装,TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口;

    #!/usr/bin/python
    # -*- coding:utf-8 -*-
    import socket
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #买手机
    phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    phone.bind(('127.0.0.1',8080)) #插电话卡
    phone.listen(5) #开机,backlog
    
    while True: #链接循环
        print('starting....')
        conn,addr=phone.accept() #接电话
        print('cliet addr',addr)
        while True: #与conn的通信循环
            try:#针对windows平台下客户端断开链接
                client_msg=conn.recv(1024) #收消息
                if not client_msg:break #针对linux系统平台下客户端断开链接
                print('client msg: %s' %client_msg)
                conn.send(client_msg.upper()) #发消息
            except Exception:
                break
        conn.close()
    phone.close()
    View Code
  • 相关阅读:
    C++ 二元作用域运算符(::)
    C 桶排序
    C 递归的选择排序
    C 归并算法
    C 可变长实参列表
    C条件编译的一些例子
    C实现将中缀算术式转换成后缀表达式
    Activiti6-数据库配置-dbconfig(学习笔记)
    idea在Terminal中使用maven指令
    Spring Boot的web开发
  • 原文地址:https://www.cnblogs.com/wangkc/p/10868811.html
Copyright © 2011-2022 走看看