tcp网络编程--(python22)

本文详细介绍了TCP网络编程的基本流程,包括客户端和服务器的开发步骤,并展示了如何搭建静态的Web服务器。通过创建socket对象,进行连接、发送和接收数据,实现客户端与服务器的通信。同时,给出了多任务服务端的实现方式,使用类结构优化服务器代码。最后,展示了如何利用TCP实现一个简单的静态Web服务器,接收HTTP请求并返回页面内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. tcp介绍

TCP 的英文全拼(Transmission Control Protocol)简称传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议。
特点:
面向连接
传输可靠

socket (简称 套接字) 是进程之间通信一个工具,好比现实生活中的插座,所有的家用电器要想工作都是基于插座进行,进程之间想要进行网络通信需要基于这个 socket。

2. tcp开发的流程

在这里插入图片描述

2.1 tcp客户端的开发

1.创建客户端套接字对象 socket
2.和服务端套接字建立连接 connect
3.发送数据 send
4.接收数据 recv
5.关闭客户端套接字 close

"""
tcp客户端
基于socket的实现方式
ubuntu的编码方式utf-8
windows的编码方式gbk
"""

import socket

# 创建socket   AF_INET ipv4  SOCK_STREAM tcp的方式
tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接服务器 包含了ip和端口
tcp_client.connect(('192.168.3.83', 6666))

# 准备数据 utf-8
data = 'hello,python'

# 数据类型的转换
data = data.encode('utf-8')

# 向服务器发发送数据
tcp_client.send(data)

# 接收数 recv要指定接收数据的大小 最大4096
recv_data = tcp_client.recv(1024)
print('未解码的数据:', recv_data)
# 接收的数据二进制的,接收完的数据要使用decode解码
recv_data = recv_data.decode('utf-8')
print(recv_data)

# 关闭
tcp_client.close()

2.2 tcp服务端的开发

1.创建服务端端套接字对象 socket
2.绑定端口号 bind
3.设置监听 listen
4.等待接受客户端的连接请求
5.接收数据 accept
6.发送数据 send
7.关闭套接字 close

"""
socket 创建套接字对象  bind 绑定端口
listen 监听   recv 接收数据
send 发送数据  close 关闭
"""

import socket

# 创建socket
tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 目前的服务器是一次性的,如果要马上释放要 设置一下socket
tcp_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

# 绑定端口 没有给定ip,默认本机的ip地址
tcp_server.bind(('', 7777))

# 监听
tcp_server.listen(10)

# 连接上返回两个值,一个客户端的socket的对象一个客户端的ip
tcp_cliect_soket, ip_port = tcp_server.accept()
print(tcp_cliect_soket)
print(f'连接的客户端:{ip_port[0]},端口{ip_port[1]}')
# 接收数据
data = tcp_cliect_soket.recv(1024)
# 回复数据
# 看一下客户端发来的数据
if len(data) != 0:
    data = data.decode('utf-8')
    print(f'客户端{ip_port[0]} 发送的数据:{data}')
else:
    print(f'客户端{ip_port[0]} 关闭了连接')
# 回复数据
data = '你好啊'.encode('utf-8')
tcp_cliect_soket.send(data)

tcp_cliect_soket.close()
tcp_server.close()

多任务的服务端

import socket
import threading


def client_task(client_socket, ip_port):
    print('连接进来了')
    while True:
        # 持续的接收客户端的信息
        data = client_socket.recv(1024).decode('utf-8')
        if len(data) != 0:
            print(f'客户端{ip_port[0]}发来的数据{data}')
        else:
            print(f'客户端{ip_port[0]}关闭了,下次再见')
            break
        # 回复
        send_data = (data + 'hello').encode('utf-8')
        client_socket.send(send_data)


if __name__ == '__main__':
    server_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    server_tcp.bind(('', 6666))
    server_tcp.listen(128)
    while True:
        tcp_client_socket, tcp_ip_port = server_tcp.accept()
        # 实现多任务
        t_client = threading.Thread(target=client_task, args=(tcp_client_socket, tcp_ip_port))
        # 设置守护线程
        t_client.setDaemon(True)
        t_client.start()
    server_tcp.close()

class实现

"""
使用类来实现tcp服务器的多任务
"""

import socket
import threading


class SockerServer(object):
    def __init__(self, port):
        self.server_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.server_tcp.bind(('', port))
        self.server_tcp.listen(128)

    def start(self):
        while True:
            tcp_client_socket, tcp_ip_port = self.server_tcp.accept()
            # 实现多任务
            t_client = threading.Thread(target=self.client_task, args=(tcp_client_socket, tcp_ip_port))
            # 设置守护线程
            t_client.setDaemon(True)
            t_client.start()
        server_tcp.close()

    def client_task(self, client_socket, ip_port):
        print('连接进来了')
        while True:
            # 持续的接收客户端的信息
            data = client_socket.recv(1024).decode('utf-8')
            if len(data) != 0:
                print(f'客户端{ip_port[0]}发来的数据{data}')
            else:
                print(f'客户端{ip_port[0]}关闭了,下次再见')
                break
            # 回复
            send_data = (data + 'hello').encode('utf-8')
            client_socket.send(send_data)


if __name__ == '__main__':
    s = SockerServer(9999)
    s.start()

3. 搭建静态的web服务器

"""
静态的web服务器
1.编写一个tcp的服务端程序
2.获取浏览器的http请求报文的数据
3.读取固定的页面数据,把页面的数据组装成http响应报文的数据发送给浏览器群
4.http响应报文数据发送完成以后,关闭服务与客户端的套接字
"""

# 1.导入模块
import socket

# 2. 创建socket对象
static_web_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
static_web_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
static_web_socket.bind(('', 4444))
static_web_socket.listen(128)

# 3.接收请求
while True:
    client, ip_port = static_web_socket.accept()
    print(f'客户端的{ip_port[0]}使用端口{ip_port[1]}连接成功')
   # 3.1 接收客户端得请求信息
    request_info = client.recv(1024).decode()
    print(request_info)
    # 4.读取资源内容
    with open('static/index.html', 'rb') as file:
        file_content = file.read()

    # 5.拼接响应报文
    response_line = 'HTTP/1.1 200 OK\r\n'
    response_head = 'Server: PSWS1.0\r\n'
    response_data = (response_line + response_head + '\r\n').encode() + file_content

    # 6.发送响应数据
    client.send(response_data)

    # 7.关闭连接
    client.close()
# 8.关闭
static_web_socket.close()

返回指定数据的

import socket
def server_start(port):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    server.bind(('', port))
    server.listen(128)
    # 接收数据
    while True:
        client, ip_port = server.accept()
        print(f'客户端连接{ip_port[0]}端口为:{ip_port[1]}成功了。。。')
        request_info = client.recv(4096).decode()
        if len(request_info) == 0:
            print('客户端关闭')
            client.close()
        else:
            # 分割请求报文
            request_path = request_info.split(' ')[1]
            print('request_path:', request_path)
            if request_path == '/':
                request_path = '/index.html'
            try:
                print('static'+request_path)
                with open('static'+request_path, 'rb') as file:
                    file_content = file.read()

            except Exception as e:
                print('异常处理')
                response_line = 'HTTP/1.1 404 NOT FOUND\r\n'
                response_head = 'Server: PSWS1.1\r\n'

                with open('static/error.html', 'rb') as file:
                    file_content = file.read()

                response_data = (response_line + response_head + '\r\n').encode() + file_content
                client.send(response_data)

            else:
                response_line = 'HTTP/1.1 200 OK\r\n'
                response_head = 'Server: PSWS1.1\r\n'
                response_data = (response_line + response_head + '\r\n').encode()+file_content
                client.send(response_data)
            finally:

                client.close()
    server.close()

            # 数据的判断

if __name__ == '__main__':
    server_start(7777)

进程实现

import socket
import threading


def server_start(port):
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    server.bind(('', port))
    server.listen(128)
    # 接收数据
    while True:
        client, ip_port = server.accept()
        print(f'客户端连接{ip_port[0]}端口为:{ip_port[1]}成功了。。。')
        p1 = threading.Thread(target=task, args=(client,))
        p1.start()
    server.close()


def task(client):
    request_info = client.recv(4096).decode()
    if len(request_info) == 0:
        print('客户端关闭')
        client.close()
    else:
        # 分割请求报文
        request_path = request_info.split(' ')[1]
        print('request_path:', request_path)
        if request_path == '/':
            request_path = '/index.html'
        try:
            print('static'+request_path)
            with open('static'+request_path, 'rb') as file:
                file_content = file.read()

        except Exception as e:
            print('异常处理')
            response_line = 'HTTP/1.1 404 NOT FOUND\r\n'
            response_head = 'Server: PSWS1.1\r\n'

            with open('static/error.html', 'rb') as file:
                file_content = file.read()

            response_data = (response_line + response_head + '\r\n').encode() + file_content
            client.send(response_data)

        else:
            response_line = 'HTTP/1.1 200 OK\r\n'
            response_head = 'Server: PSWS1.1\r\n'
            response_data = (response_line + response_head + '\r\n').encode()+file_content
            client.send(response_data)
        finally:

            client.close()


if __name__ == '__main__':
    server_start(7777)

class:

import socket
import threading


class Server_Web(object):
    def __init__(self, port):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.server.bind(('', port))
        self.server.listen(128)

    def start(self):
        # 接收数据
        while True:
            client, ip_port = self.server.accept()
            print(f'客户端连接{ip_port[0]}端口为:{ip_port[1]}成功了。。。')
            p1 = threading.Thread(target=self.task, args=(client,))
            p1.start()
        server.close()

    def task(self, client):
        request_info = client.recv(4096).decode()
        if len(request_info) == 0:
            print('客户端关闭')
            client.close()
        else:
            # 分割请求报文
            request_path = request_info.split(' ')[1]
            print('request_path:', request_path)
            if request_path == '/':
                request_path = '/index.html'
            try:
                print('static'+request_path)
                with open('static'+request_path, 'rb') as file:
                    file_content = file.read()

            except Exception as e:
                print('异常处理')
                response_line = 'HTTP/1.1 404 NOT FOUND\r\n'
                response_head = 'Server: PSWS1.1\r\n'

                with open('static/error.html', 'rb') as file:
                    file_content = file.read()

                response_data = (response_line + response_head + '\r\n').encode() + file_content
                client.send(response_data)

            else:
                response_line = 'HTTP/1.1 200 OK\r\n'
                response_head = 'Server: PSWS1.1\r\n'
                response_data = (response_line + response_head + '\r\n').encode()+file_content
                client.send(response_data)
            finally:

                client.close()


if __name__ == '__main__':
    s = Server_Web(8888)
    s.start()

利用sys的参数argv实现:

import socket
import threading
import sys


class Server_Web(object):
    def __init__(self, port):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        self.server.bind(('', port))
        self.server.listen(128)

    def start(self):
        # 接收数据
        while True:
            client, ip_port = self.server.accept()
            # print(f'客户端连接{ip_port[0]} 端口为:{ip_port[1]}成功了。。。')
            p1 = threading.Thread(target=self.task, args=(client,))
            p1.start()
        server.close()

    def task(self, client):
        request_info = client.recv(4096).decode()
        if len(request_info) == 0:
            print('客户端关闭')
            client.close()
        else:
            # 分割请求报文
            request_path = request_info.split(' ')[1]
            print('request_path:', request_path)
            if request_path == '/':
                request_path = '/index.html'
            try:
                print('static'+request_path)
                with open('static'+request_path, 'rb') as file:
                    file_content = file.read()

            except Exception as e:
                print('异常处理')
                response_line = 'HTTP/1.1 404 NOT FOUND\r\n'
                response_head = 'Server: PSWS1.1\r\n'

                with open('static/error.html', 'rb') as file:
                    file_content = file.read()

                response_data = (response_line + response_head + '\r\n').encode() + file_content
                client.send(response_data)

            else:
                response_line = 'HTTP/1.1 200 OK\r\n'
                response_head = 'Server: PSWS1.1\r\n'
                response_data = (response_line + response_head + '\r\n').encode()+file_content
                client.send(response_data)
            finally:

                client.close()


if __name__ == '__main__':
    # 需要在服务器下运行
    if len(sys.argv) != 2:
        print('pytonh3 xxx.py 端口号')
        exit(1)
    if sys.argv[1].isdigit():
        s = Server_Web(8888)
        s.start()
    else:
        print('pytonh3 xxx.py 端口号')


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长安有故里y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值