网络编程--tcp客户端和tcp服务器端

1、tcp客户端

import socket

# 1、创建客户端套接字对象(IPv4:socket.AF_INET, TCP:socket.SOCK_STREAM)
tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2、和服务器端建立套接字连接
tcp_client_socket.connect(('192.168.15.62', 8080))

# 3、发送数据到服务器端
data = '?'.encode('gbk')
tcp_client_socket.send(data)

# 4、接收服务器端返回的数据
recv_data = tcp_client_socket.recv(1024).decode('gbk')
print(f'服务器端响应:{recv_data}')

# 5、关闭连接
tcp_client_socket.close()

2、tcp服务器端

import socket

# 创建服务端套接字对象
tcp_sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 设置端口号复用,让程序退出端口后立即释放端口号
# tcp_sever_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

# 给程序绑定端口号
tcp_sever_socket.bind(('', 8080))

# 设置监听
tcp_sever_socket.listen(128)

# 等待客户端的建立连接请求
conn_socket, ip_port = tcp_sever_socket.accept()
# 接收客户端的ip地址和端口号
print(f'客户端的ip地址和端口号:{ip_port}')

# 接收客户端发送的数据
recv_data = conn_socket.recv(1024).decode('gbk')
print(f'接收用户的数据是:{recv_data}')

# 准备发送的数据
send_data = ('正在接收数据·····,问题正在处理中.....'.encode('gbk'))
conn_socket.send(send_data)

# 关闭套接字对象
conn_socket.close()
tcp_sever_socket.close()

3、tcp服务器多线程版本

import socket
import threading


def reply_request(conn_socket, ip_port):
    # 10、循环处理客户端的请求
    while True:
        # 7、接收客户端的请求
        recv_data = conn_socket.recv(1024)
        if recv_data:
            print(f'客户端的信息:{ip_port}')
            print("客户端发送的数据:", recv_data.decode('gbk'))
            # 8、返回数据给客户端
            conn_socket.send('信息已收到!'.encode('gbk'))
        else:
            print(ip_port, '客户端已下线')
            break

    # 关闭套接字对象
    conn_socket.close()


if __name__ == '__main__':
    # 1、创建TCP服务端的套接字对象
    tcp_sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 设置端口复用
    tcp_sever_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

    # 2、绑定IP和端口号
    tcp_sever_socket.bind(('', 8080))

    # 3、开始监听
    tcp_sever_socket.listen(128)
    while True:
        # 4、等待客户端连接,产生新的套接字
        conn_socket, ip_port = tcp_sever_socket.accept()

        # 5、创建多线程
        sub_thread = threading.Thread(target=reply_request, args=(conn_socket, ip_port))

        # 设置守护主线程
        sub_thread.setDaemon(True)

        # 6、启动线程
        sub_thread.start()

4、静态Web服务器之返回固定页面

import socket

# 创建套接字对象
tcp_sever_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 设置端口复用
tcp_sever_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

# 绑定端口号
tcp_sever_socket.bind(('', 9000))

# 开始监听
tcp_sever_socket.listen(128)
while True:
    # 等待接收客户端的连接请求,并创建新的套接字
    conn_socket, ip_port = tcp_sever_socket.accept()

    # 接收客户端的http请求
    recv_client_data = conn_socket.recv(4096)
    # 对接收的http请求数据进行解码
    recv_data_content = recv_client_data.decode('utf-8')
    print('接收到客户端浏览器的http请求为:', recv_client_data)

    # 读取文件数据
    with open('Static_Sever/Nothing.png', 'rb') as file:
        # with open('D:/Static_Sever/index01.html', 'rb') as file:
        # with open('D:/Static_Sever/index.html', 'rb') as file:
        file_data = file.read()

    # 响应行
    response_line = 'HTTP/1.1 200 OK\r\n'

    # 响应头
    response_header = 'Server:PWS1.0\r\n'
    # response_header = 'Server:PWS1.0\r\nContent-type:text/html; charset=utf-8\r\n'  # utf-8对于html中内容是通用的

    # 响应体
    response_body = file_data

    # 拼接响应报文
    response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body

    # 发送http响应报文
    conn_socket.send(response_data)

    # 关闭套接字
    conn_socket.close()

5、静态Web服务器之返回指定页面


while True:
    # 等待接收客户端连接请求
    conn_client_socket, ip_port = tcp_server_socket.accept()

    # 接收HTTP请求报文
    recv_client_data = conn_client_socket.recv(4096)
    # 对接收数据进行转码
    if len(recv_client_data) > 0:
        recv_client_content = recv_client_data.decode('utf-8')
        print(recv_client_content)

        # 获取用户的请求资源路径
        request_path = recv_client_content.split(' ', maxsplit=2)[1]

        # 如果获取的请求路径没输入,默认为/
        if request_path == '/':
            request_path = '/index.html'

        # 发送响应报文
        with open('Static_Sever' + request_path, 'rb') as file:
            file_data = file.read()

        # 响应行
        response_line = 'HTTP/1.1 200 OK\r\n'

        # 响应头
        response_header = 'Server:PWB1.0\r\n'

        # 响应体
        response_body = file_data

        # 组装响应报文
        response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body

        # 发送响应报文
        conn_client_socket.send(response_data)

        # 关闭套接字对象
        conn_client_socket.close()

6、静态Web服务器之返回指定页面(进阶版)

import socket

if __name__ == '__main__':
    # 1、创建套接字对象
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2、绑定端口
    tcp_server_socket.bind(('', 8080))
    # 3、设置监听
    tcp_server_socket.listen(128)
    while True:
        # 4、接收客户端连接请求
        conn_socket, ip_port = tcp_server_socket.accept()
        # 5、接收数据(HTTP请求报文)
        recv_client_data = conn_socket.recv(4096)
        if len(recv_client_data) > 0:
            recv_client_content = recv_client_data.decode('utf-8')
            # print(recv_client_content)
            # 获取用户请求的资源路径(资源格式 => GET  请求资源路径   HTTP/1.1)
            request_path = recv_client_content.split(' ', maxsplit=2)[1]
            # print(request_path)

            # 特殊情况:如果request_path == '/',则应该让其访问项目的首页!
            if request_path == '/':
                request_path = '/index.html'

            # 6、发送数据(HTTP响应报文)
            try:
                with open('Static_Sever' + request_path, 'rb') as f:  # 'static' + request_path = static/hlw.png
                    file_data = f.read()
            except Exception as e:
                # 如果文件不存在,则返回HTTP/1.1 404 Not Found
                # ① 响应行
                response_line = 'HTTP/1.1 404 Not Found\r\n'
                # ② 响应头
                response_header = 'Server:PWB1.0\r\n'
                # ③ 响应体
                with open('Static_Sever/error.html', 'rb') as f:
                    file_data = f.read()

                response_body = file_data
                # ④ 组装响应数据
                response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
                conn_socket.send(response_data)
            else:
                # ① 响应行
                response_line = 'HTTP/1.1 200 OK\r\n'
                # ② 响应头
                response_header = 'Server:PWB1.0\r\n'
                # ③ 响应体
                response_body = file_data
                # ④ 组装响应数据
                response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
                conn_socket.send(response_data)
            finally:
                # 7、关闭客户端与服务器端新产生套接字对象
                conn_socket.close()

7、静态Web服务器之多任务版本(多线程)

import socket
import threading


def handle_client_request(conn_socket):
    # 接收客户端发过来的HTTP请求
    recv_client_data = conn_socket.recv(4096)
    if len(recv_client_data) > 0:
        # 数据解码
        recv_client_content = recv_client_data.decode('utf-8')
        # print(recv_client_content)

        # 获取客户端资源请求路径
        request_path = recv_client_content.split(' ', maxsplit=2)[1]
        if request_path == '/':
            request_path = '/index.html'
        # 打开文件,获取客户端请求数据
        try:
            with open('Static_Sever' + request_path, 'rb') as f:
                file_data = f.read()
        except Exception as e:
            # 找不到文件,返回404,Not Found
            # 响应行
            response_line = 'HTTP/1.1 404 Not Found\r\n'

            # 响应头
            response_header = 'Server:PWB1.0\r\n'

            # 响应体
            with open('Static_Sever/error.html', 'rb') as f:
                file_data = f.read()
            response_body = file_data

            # 组装http响应报文
            response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body

            # 发送http响应报文
            conn_socket.send(response_data)
        else:
            # 响应行
            response_line = 'HTTP/1.1 200 OK\r\n'

            # 响应头
            response_header = 'Server:PWB1.0\r\n'

            # 响应体
            response_body = file_data

            # 组装响应报文
            response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body

            # 发送响应报文
            conn_socket.send(response_data)
        finally:
            conn_socket.close()


if __name__ == '__main__':
    # 创建套接字对象
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 端口复用
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

    # 绑定端口号
    tcp_server_socket.bind(('', 8080))

    # 设置监听
    tcp_server_socket.listen(128)

    while True:
        # 等待客户端的连接请求
        conn_socket, ip_port = tcp_server_socket.accept()

        # 创建子线程
        sub_thread = threading.Thread(target=handle_client_request, args=(conn_socket,))

        # 设置守护主线程
        sub_thread.setDaemon(True)
        sub_thread.start()

8、静态Web服务器之面向对象版本(类)

import socket
import threading


class HttpWebServer(object):
    # 定义__init__方法,初始化套接字对象
    def __init__(self):
        # 创建套接字对象
        tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 端口复用
        tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
        # 绑定端口
        tcp_server_socket.bind(('', 8080))
        # 设置监听
        tcp_server_socket.listen(128)
        # 将tcp_server_socket设置为对象属性
        self.tcp_server_socket = tcp_server_socket

    @staticmethod
    def handle_client_request(conn_socket):
        # 接收客户端传送的请求数据
        recv_client_data = conn_socket.recv(4096)
        if len(recv_client_data) > 0:
            # 将客户端请求数据转码
            recv_client_content = recv_client_data.decode('utf-8')
            print(recv_client_data)
            # 获取客户端请求资源路径
            request_path = recv_client_content.split(' ', maxsplit=2)[1]
            if request_path == '/':
                request_path = '/index.html'
            # http响应报文
            try:
                with open('Static_Sever' + request_path, 'rb') as f:
                    file_data = f.read()

            except Exception as e:
                # 返回404 Not Found
                # 响应行
                response_line = 'HTTP/1.1 404 Not Found\r\n'
                # 响应头
                response_header = 'Server:PWB1.0\r\n'
                # 响应体
                with open('Static_Sever/error.html', 'rb') as f:
                    file_data = f.read()
                response_body = file_data
                # 组装响应报文
                response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
                # 发送响应报文
                conn_socket.send(response_data)
            else:
                # 响应行
                response_line = 'HTTP/1.1 OK\r\n'
                # 响应头
                response_header = 'Server:PWB1.0\r\n'
                # 响应体
                response_body = file_data
                # 组合响应报文
                response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_body
                # 发送响应报文
                conn_socket.send(response_data)
            finally:
                conn_socket.close()

    def start(self):
        while True:
            # 接收客户端的HTTP连接请求
            conn_socket, ip_port = self.tcp_server_socket.accept()
            # 创建子进程
            sub_thread = threading.Thread(target=self.handle_client_request, args=(conn_socket,))
            # 设置守护主进程
            sub_thread.setDaemon(True)
            # 启动子进程
            sub_thread.start()


if __name__ == '__main__':
    # 创建类的对象
    web_server = HttpWebServer()

    # 启动Web程序
    web_server.start()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值