zoukankan      html  css  js  c++  java
  • python之网络编程

    软件开发的架构

    我们了解涉及到的俩个程序之间的通讯大致可以分为俩种:

    第一种:应用类:qq、微信、网盘、这一类需要安装的桌面应用

    第二种:web类:比如百度、知乎、博客园等使用浏览器就可以使用的应用

    这些应用的本质上其实都是两个程序之间的通讯,而这俩个分类对应了俩个开发的架构

    1、C/S 架构

    C/S 即:Client与Server, 中文的意思是:客户端与服务端架构.这种架构也是从用户层面(也可以是物理层面)来划分的

    这里的客户端一般是泛指的是客户端程序EXE,程序先安装后,才能运行在用户的电脑上,对用户的电脑操作系统环境依赖比较大

     2、B/S  架构

    B/S 即 Browser 与 Server 中文的意思:浏览器与服务端架构、这种架构是从用户层面来划分的

    Browser浏览器,其实也是一种Client客户端,只是这个客户端不需要大家去安装什么应用程序,只需要在浏览器上通过HTTP请求服务器相关的资源(网页资源),客户端Browser浏览器就可以进行增删改查

    tcp协议和udp协议

    用于应用程序之间的通信.如果说ip地址和mac地址帮我们确定唯一一台机器,那么我们怎么找到一台机器上的软件呢?

    端口

    我们知道、一台拥有ip地址的主机可以提供许多服务,比如web服务,FTP服务,SMTP服务,这些服务完全可以通过一个ip地址来实现,那么,主机是怎样区分不同网络服务?显然不能只靠IP地址,因为IP地址与网络服务的关系的一对多的关系.实际上通过“IP地址加端口号来区分不同的服务的”

    TCP协议

    当应用程序希望通过TCP与另一个应用程序通信时,它会发送一个通信请求,这个通信请求必须被送到一个确切的地址,在双方握手之后,TCP将俩个程序之间建立一个全双工的通信。

    这个全双工的的通信将占用俩个计算机之间的通信线路,直到它被一方或者双方都关闭为止

     三次握手

    TCP是因特网中的传输层协议,使用三次握手协议建立连接,当主动方发出SYN连接请求后,等待对方回答SYN+ACK,并最终对方的syn执行ACK确认.

    这种建立连接的方法可以防止产生错误的连接.

    TCP三次握手过程如下:

    客户端方式SYN(SEQ = x)报文给服务器端,进入SYN_SEND状态.

    服务器端收到SYN报文,回应一个SYN(SEQ = y)ACK(ACK = x+1)报文,进入SYN_RECV状态

    客户端收到服务器端SYN报文,回应一个ACK(ACK = y+1)报文,进入Establishe状态

    三次握手完成,TCP客户端和服务器端成功的建立连接,可以开始传输数据了。

    四次挥手:

    建立一个连接需要三次握手,而终止一个连接要经过四次挥手,这是TCP半关闭(half-close)造成的

    1. 某个应用进程首先close,称该端执行“主动关闭”(active-close).该端的tcp于是发送一个FIN分节,表示数据发送完毕
    2. 接受这个FIN对端执行“被动关闭”(Passive close) 这个FIN由TCP确认(注意:FIN的接受也作为一个文件结束符(end-of-fiel)传递给接收应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。)
    3. 一段时间后,接收在文件结束符的应用进程将调用close关闭它的套接字,这导致它的TCP也发送一个FIN
    4. 接收这个最终的FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN

    既然每个方向都需要一个FIN和一个ACK,因此通常需要4个分节。

    UDP协议

    当应用程序希望通过UDP与一个应用程序通信时,传输数据之前源端和终端不建立连接。

    当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。

    TCP和UDP的对比

    TCP---传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。 

    UDP---用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快

    套接字(socket)初识

    基于TCP协议的socket

    tcp是基于链接的,必须先启动服务端,然后再启动客户端去连接服务端.

    server端

    import socket
    sk = socket.socket()
    sk.bind(('127.0.0.1',8898))  # 把地址绑定到套接字
    sk.listen()  # 监听链接
    conn,addr = sk.accept()  # 接受客户端链接
    ret = conn.recv(1024)  # 接收客户端信息
    print(ret)  # 打印客户端信息
    conn.send(b'hi')  # 向客户端发送信息
    conn.close()  # 关闭客户端套接字
    sk.close()  # 关闭服务器套接字(可选)

    client端

    import socket
    sk = socket.socket()  # 创建客户套接字
    sk.connect(('127.0.0.1',8898))  # 尝试连接服务器
    sk.send(b'hello!')
    ret = sk.recv(1024)  # 对话(发送/接收)
    print(ret)
    sk.close()  # 关闭客户套接字

     端口被占用

    # 加入一条socket配置,重用ip和端口
    import socket
    from socket import SOL_SOCKET,SO_REUSEADDR
    sk = socket.socket()
    sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)  # 就是它,在bind前加
    sk.bind(('127.0.0.1',8898))  # 把地址绑定到套接字
    sk.listen()  # 监听链接
    conn,addr = sk.accept() # 接受客户端链接
    ret = conn.recv(1024)   # 接收客户端信息
    print(ret)  # 打印客户端信息
    conn.send(b'hi')  # 向客户端发送信息
    conn.close()  # 关闭客户端套接字
    sk.close()  # 关闭服务器套接字(可选)

     基于UDP协议的socket

    udp是无链接的,启动服务之后可以直接接受消息 , 不需要提前建立链接

    简单使用:server端

    import socket
    udp_sk = socket.socket(type=socket.SOCK_DGRAM)   #创建一个服务器的套接字
    udp_sk.bind(('127.0.0.1',9000))        #绑定服务器套接字
    msg,addr = udp_sk.recvfrom(1024)
    print(msg)
    udp_sk.sendto(b'hi',addr)                 # 对话(接收与发送)
    udp_sk.close()                         # 关闭服务器套接字

    client端:

    import socket
    ip_port=('127.0.0.1',9000)
    udp_sk=socket.socket(type=socket.SOCK_DGRAM)
    udp_sk.sendto(b'hello',ip_port)
    back_msg,addr=udp_sk.recvfrom(1024)
    print(back_msg.decode('utf-8'),addr)

    QQ聊天:

    server

    #_*_coding:utf-8_*_
    import socket
    ip_port=('127.0.0.1',8081)
    udp_server_sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    udp_server_sock.bind(ip_port)
    
    while True:
        qq_msg,addr=udp_server_sock.recvfrom(1024)
        print('来自[%s:%s]的一条消息:33[1;44m%s33[0m' %(addr[0],addr[1],qq_msg.decode('utf-8')))
        back_msg=input('回复消息: ').strip()
    
        udp_server_sock.sendto(back_msg.encode('utf-8'),addr)
    
    server

     client

    #_*_coding:utf-8_*_
    import socket
    BUFSIZE=1024
    udp_client_socket=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    
    qq_name_dic={
        '金老板':('127.0.0.1',8081),
        '哪吒':('127.0.0.1',8081),
        'egg':('127.0.0.1',8081),
        'yuan':('127.0.0.1',8081),
    }
    
    
    while True:
        qq_name=input('请选择聊天对象: ').strip()
        while True:
            msg=input('请输入消息,回车发送,输入q结束和他的聊天: ').strip()
            if msg == 'q':break
            if not msg or not qq_name or qq_name not in qq_name_dic:continue
            udp_client_socket.sendto(msg.encode('utf-8'),qq_name_dic[qq_name])
    
            back_msg,addr=udp_client_socket.recvfrom(BUFSIZE)
            print('来自[%s:%s]的一条消息:33[1;44m%s33[0m' %(addr[0],addr[1],back_msg.decode('utf-8')))
    
    udp_client_socket.close()

     

  • 相关阅读:
    ASP.NET 表单验证 Part.1(理解表单验证)
    Silverlight 简介 Part.3(设计 Siverlight 页面)
    ASP.NET 成员资格 Part.3(LoginStatus、LoginView、PasswordRecovery)
    ASP.NET 网站部署 Part.1(安装IIS、复制文件部署网站)
    ASP.NET Dynamic Data Part.1(创建动态数据应用程序)
    ASP.NET 安全模型 Part.2(SSL)
    ASP.NET MVC Part.2(扩展基本的 MVC 应用程序)
    ASP.NET 网站部署 Part.2(使用 Web 部署)
    开发高级 Web 部件
    创建 Web 部件(WebPart 类、简单的 Web 部件)
  • 原文地址:https://www.cnblogs.com/Zhao--C/p/10320109.html
Copyright © 2011-2022 走看看