648 views
Python高级技巧

6.socket编程-TCP

文章目录

socket编程-TCP

socket简介

socket又称“套接字“,应用程序通常通过“套接字“向网络发出请求或者应答网络请求,
使主机间或者一台计算机上的进程间可以通讯。
白话说,socket就是两个节点为了互相通信,而在各自家里装的一部‘电话‘。

IP地址的分类

端口分类

1.知名端口(well known ports)

- 80端口分配给HTTP服务
- 21端口分配给FTP服务    
  - 范围是从0到1023

2.动态端口
动态端口的范围是从1024-65535

TCP/IP协议简介

TCP/IP协议是Transmission Control Protocol/Internet Protocol的简写,即传输控制协议/因特网互联协议,
又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。
TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。
协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。

- TCP协议,传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议
- TCP通信需要经过创建连接、数据传送、终止连接三个步骤。
- TCP通信模型中,在通信开始之前,一定要先建立相关连接,才能发生数据。

TCP特点
- 面向连接
    - 通信双方必须先建立连接才能进行数据的传输
- 可靠传输
    - TCP采用发送应答机制
    - 超时重传
    - 错误校验
    - 流量控制和阻塞管理

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

TCP/IP网络模型四层模型从根本上和OSI七层网络模型是一样的,只是合并了几层

TCP与UDP区别总结

1、TCP面向连接;UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;
   UDP尽最大努力交付,即不保证可靠交付
3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP对系统资源要求较多,UDP对系统资源要求较少。

TCP通信流程

TCP客户端

'''
1.创建socket
2.链接服务器
3.接收数据(最大接收1024个字节)
4.关闭套接字
'''
import socket
# from socket import *
def main():
    # 创建TCP套接字
    tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # tcp_client = socket(AF_INET, SOCK_STREAM)
    server_ip = input("server ip:")
    server_port = int(input("server port:"))
    # 链接服务器
    tcp_client.connect_ex((server_ip, server_port))
    # 发送数据
    send_data = input("发送的数据:")
    tcp_client.send(send_data.encode())
    # 接收数据  阻塞
    recvdata = tcp_client.recv(1024)
    print(recvdata.decode('gbk'))
    tcp_client.close()

if __name__ == '__main__':
    main()

TCP服务端

'''
TCP服务端

1 socket创建套接字
2 bind绑定IP和port     固定的
3 listen使套接字变为可以被动链接
4 accept等待客户端的链接
5 recv/send接收发送数据

类似于:
1 买手机
2 插上手机卡
3 设置手机为正常接听状态
4 等待别人打电话
'''
import socket

def main():
    # tcp的套接字
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定信息
    tcp_server.bind(("192.168.0.161", 7890))
    # 主动变被动
    tcp_server.listen(128)
    print("--1--")
    # accept() -> (socket object, address info)
    new_client_socket, client_addr = tcp_server.accept()
    # print(client_addr)
    print("--2--")
    # 接收数据
    recv_data = new_client_socket.recv(1024)
    print(recv_data)
    # 发送数据
    new_client_socket.send('haha'.encode('gbk'))
    new_client_socket.close()
    tcp_server.close()

if __name__ == '__main__':
    main()

TCP服务端为多个客户端服务

'''
TCP服务端为多个客户端服务
'''
import socket

def main():
    # tcp的套接字
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定信息
    tcp_server.bind(("192.168.0.161", 7890))
    # 为多个客户端服务
    while True:
        # 主动变被动
        tcp_server.listen(128)
        # accept() -> (socket object, address info)
        new_client_socket, client_addr = tcp_server.accept()
        # print(client_addr)
        # 为客户端多次服务
        while True:
            # 接收数据  阻塞
            recv_data = new_client_socket.recv(1024)
            # print(recv_data)
            # 客户端发送过来数据
            # 客户端断开连接
            if recv_data.decode('gbk'):
                # 发送数据
                new_client_socket.send('haha'.encode('gbk'))
            else:
                break
        # 关闭客户端
        new_client_socket.close()
    tcp_server.close()

if __name__ == '__main__':
    main()

文件下载客户端

'''
TCP客户端

1.创建套接字
2.连接服务器
3.要下载的文件名称
4.发送文件下载的请求
5.接收服务端发送过来的数据
6.保存文件
7.关闭套接字
'''

import socket

def main():
    # 创建TCP套接字
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # server_ip = input("server ip:")
    # server_port = int(input("server port:"))
    # 连接服务器
    tcp_client_socket.connect(('192.168.0.161', 7890))
    file_name = input('请输入文件名称:')
    # 发送文件下载请求
    tcp_client_socket.send(file_name.encode('gbk'))
    # 接收文件
    recv_data = tcp_client_socket.recv(1024*1024)
    if recv_data:
        # 保存文件
        with open('接收'+file_name, 'wb') as f:
            f.write(recv_data)
    # 关闭套接字
    tcp_client_socket.close()

if __name__ == '__main__':
    main()

文件下载服务端

'''
TCP服务端

创建套接字
绑定信息
listen 主动变被动
accept 等待客户端的链接
发送/接收
'''

import socket

def send_file_client(new_client_socket):
    # 接收口红的发送过来的数据
    file_name = new_client_socket.recv(1024).decode()
    content = b""
    try:
        with open(file_name, 'rb') as f:
            content = f.read()
    except:
        print("no download file:%s" % file_name)
    new_client_socket.send(content)
    new_client_socket.close()

def main():
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_server_socket.bind(("", 7890))
    tcp_server_socket.listen(128)
    new_client_socket, client_addr = tcp_server_socket.accept()
    # 给客户端返回文件内容
    send_file_client(new_client_socket)
    tcp_server_socket.close()

if __name__ == '__main__':
    main()
影子专属博客 赣ICP备17013143号