python高级-socket和web相关

目录

一、socket

1.客户端开发

2.tcp客户端

3.tcp服务端

4.连接的注意事项

5.多任务服务端

二、静态web

1.请求报文

2.响应头

3.静态web服务器

4.socket静态页面

5.多进程模拟404和200状态码

6.面向对象多任务

结语


一、socket

python高级-socket和web相关_第1张图片

1.客户端开发

  1. 创建客户端套接字对象
  2. 和服务端套接字建立连接
  3. 发送数据
  4. 接收数据
  5. 关闭客户端套接字
  6. 对应状态

python高级-socket和web相关_第2张图片

导入socket模块

import socket

创建客户端socket对象

socket.socket(AddressFamily,Type)

参数说明:

AddressFamily表示ip地址类型,分为ipv4和ipv6

Type表示传输协议类型

方法说明

  • connect(host,port)表示和服务端套接字建立连接,host是服务器ip地址,port是应用程序的端口号
  • send(data)表示发送数据,data是二进制数据
  • recv(buffersize)表示接收数据,buffersize是每次接收数据的长度

2.tcp客户端


import socket



if __name__ = 'main':
    #socket.AF_INET:代表ipv4     socket.SOCK_STREAM tcp传输协议
    tcp_client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
    #服务端192.168.131.62 8000端口建立连接
    tcp_client_socket.connect(('192.168.131.62',8000))
    
    #代码执行到此,说明链接建立成功
    #准备发送的数据
    send_data = "您好服务端,我是客户端的小明".encode("gbk")
    
    #发送数据
    tcp_client_socket.send(send_data)
    
    #接收数据,这次接受的数据最大字节数是1024
    recv_data = tcp_client_socket.recv(1024)
    
    #返回的直接是服务端程序发送的二进制
    print(recv_data)
    
    #解码输出
    recv_content = recv_data.decode("gbk")
    print("接受服务端的数据为:",recv_content)
    
    #关闭套接字
    tcp_client_socket.close()
    

python高级-socket和web相关_第3张图片

3.tcp服务端

python高级-socket和web相关_第4张图片

python高级-socket和web相关_第5张图片


import socket



if __name__ == '__main__':

    #socket.AF_INET:代表ipv4     socket.SOCK_STREAM tcp传输协议
    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(("",8989))

    #设置最大等待建立连接的个数,目前是单任务服务端,后续会用多任务
    tcp_server_socket.listen(128)

    #解包
    service_client_socket,ip_port = tcp_server_socket.accept()

    #代码执行到此说明连接建立成功
    print("ip和port: ",ip_port)

    #接受客户端发送的数据,这次接受数据的最大字节数是(1024)
    recv_data = service_client_socket.recv(1024)

    recv_data_len = len(recv_data)
    print("接受客户端的数据的长度为:",recv_data_len)
    print("接受客户端的数据为:",recv_data)

    #解码
    rev_de_data = recv_data.decode("gbk")
    print("解码后的客户端数据: ",rev_de_data)

    #关闭套接字
    tcp_server_socket.close()


python高级-socket和web相关_第6张图片

4.连接的注意事项

  • 当tcp客户端程序想和tcp服务端程序进行通信的时候必须要先建立连接
  • tcp客户端程序一般不一定需要绑定端口号,因为客户端时主动发起连接的
  • TCP服务端程序必须绑定端口号,否则客户端找不到这个tcp服务端程序
  • listen后的套接字时被动套接字,只负责接收新的客户端连接请求,不能收发消息。
  • 当TCP客户端程序和TCP服务端程序连接成功后,TCP服务端程序会产生一个新的套接字,收发客户端使用该套接字
  • 关闭accept返回的套接字意味着和这个客户端已经通信完毕。
  • 关闭listen后的套接字意味着服务端的套接字已经关闭了,会导致新的客户端不能连接服务端,但之前已经连接成功的客户端还能正常通信。
  • 当客户端的套接字调用close后,服务端的recv会解阻塞,返回的数据长度为0,服务端可以通过返回数据的长度来判断客户端是否已经下线,反之服务端关闭套接字,客户端的recv也会阻塞,返回的数据长度为0。

5.多任务服务端

  • 编写一个tcp服务端程序,循环等待接受客户端的连接请求
  • 当客户端和服务端建立连接成功,创捷子线程,使用子线程专门处理客户端的请求,防止主线程阻塞
  • 把创建的子线程设置为守护主线程,防止主线程无法退出
import socket
import threading

def handle_client_r(service_client_socket,ip_port):
    #单客户端内部循环检测
    while True:
        #循环接受客户端发送的数据
        #接受客户端发送的数据
        recv_d = service_client_socket.recv(1024)

        #容器类型判断是否有数据可以直接使用if语句进行判断,如果容器类型里面有数据表示条件成立
        #容器类型:列表、字典、元组、字符串、set、range、二进制数组
        if recv_d:
            print(recv_d.decode("gbk"),ip_port)

            #回复
            service_client_socket.send("你好我是服务端。。。。".encode("gbk"))
        else:
            print("客户端下线了: ",ip_port)
            break

    service_client_socket.close()
if __name__ == '__main__':
    #创建tcp服务端套接字
    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(("",9090))

    #设置监听,listen后的套接字是被动套接字,只负责接收客户端的连接请求
    tcp_server_socket.listen(128)
    
    #多客户端socket
    while True:
        #等待接收客户端的连接请求
        service_client_s,ip_port = tcp_server_socket.accept()
        print("客户端连接成功: ",ip_port)

        #当客户端和服务端建立连接成功后,需要创建一个子线程,不同子线程负责接受不同客户端的消息
        sub_t = threading.Thread(target=handle_client_r,args=(service_client_s,ip_port))

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

        #启动子线程
        sub_t.start()

python高级-socket和web相关_第7张图片

import socket
import threading

class SocketServer(object):
    def __init__(self):
        # 创建tcp服务端套接字
        self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

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

        # 绑定端口号
        self.tcp_server_socket.bind(("",6666))

        # 设置监听,listen后的套接字是被动套接字,只负责接收客户端的连接请求
        self.tcp_server_socket.listen(128)

    def start(self):
        #多客户端socket
        while True:
            #等待接收客户端的连接请求
            service_client_s,ip_port = self.tcp_server_socket.accept()
            print("客户端连接成功: ",ip_port)

            #当客户端和服务端建立连接成功后,需要创建一个子线程,不同子线程负责接受不同客户端的消息
            sub_t = threading.Thread(target=self.client_t,args=(service_client_s,ip_port))

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

            #启动子线程
            sub_t.start()

        self.tcp_server_socket.close()

    def client_t(self,service_client_socket,ip_port):
        print(ip_port,"  连接上来了")
        #单客户端内部循环检测
        while True:
            #循环接受客户端发送的数据
            #接受客户端发送的数据
            recv_d = service_client_socket.recv(1024).decode('gbk')

            #容器类型判断是否有数据可以直接使用if语句进行判断,如果容器类型里面有数据表示条件成立
            #容器类型:列表、字典、元组、字符串、set、range、二进制数组
            if len(recv_d) != 0:
                print(f'客户端{ip_port[0]} 发来的消息是{recv_d}')
            else:
                print(f'客户端{ip_port[0]} 已断开连接,下次再见。。。。')
                break
            send_data = ('Hello 我是服务端 --'+recv_d).encode('gbk')
            service_client_socket.send(send_data)

if __name__ == '__main__':
    server = SocketServer()
    server.start()

python高级-socket和web相关_第8张图片


二、静态web

1.请求报文

python高级-socket和web相关_第9张图片

python高级-socket和web相关_第10张图片

2.响应头

python高级-socket和web相关_第11张图片

python高级-socket和web相关_第12张图片

响应码

python高级-socket和web相关_第13张图片

3.静态web服务器

python3 -m http.server

http://127.0.0.1:8000/index1.html

python高级-socket和web相关_第14张图片

http://0.0.0.0:8000/

python高级-socket和web相关_第15张图片

4.socket静态页面


import socket



if __name__ == '__main__':
    #创建tcp服务端套接字
    tcp_serv_s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

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

    #端口绑定
    tcp_serv_s.bind(("",9000))

    #设置监听
    tcp_serv_s.listen(128)

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

        #代码执行到此,说明连接建立成功
        recv_c_d = new_socket.recv(4096)

        #对接收的客户端的请求包头进行二进制解码
        recv_c_con = recv_c_d.decode("utf-8")
        print(recv_c_con)

        with open("./index1.html",'rb') as f:
            f_d = f.read()

        #相应行
        response_l = "HTTP/1.1 200 OK\r\n"

        #响应头
        response_h = "Server: PWS1.0\r\n"

        #响应体
        response_b = f_d

        #拼接响应报文
        res_d = (response_l+response_h+"\r\n").encode("utf-8") + response_b

        #发送数据
        new_socket.send(res_d)

new_socket.close()

python高级-socket和web相关_第16张图片

python高级-socket和web相关_第17张图片

5.多进程模拟404和200状态码

import multiprocessing
import socket


def serv_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]} 端口连接成功")

        p = multiprocessing.Process(target=task,args=(client,))
        p.start()
    server.close()

def task(client):
    request_data = client.recv(1024).decode('utf-8')
    if len(request_data) == 0:
        client.close()
    else:
        request_path = request_data.split(' ')[1]
        print("请求地址是: ",request_path)

        print("request:  ",request_path)

        if request_path == '/':
            request_path = 'index1.html'

        try:
            with open('./'+request_path,'rb') as f:
                file_con = f.read()
        except Exception as e:
            response_line = "HTTP/1.1 404 NOT FOUND\r\n"
            response_head = "Server: PSWS1.1\r\n"
            with open('./err.html','rb') as f:
                error_data = f.read()

            response_data = (response_line+response_head+'\r\n').encode('utf-8') + error_data

            client.send(response_data)

        else:
            response_line = "HTTP/1.1 200 OK\r\n"
            response_head = "Server: PSWS1.1\r\n"
            with open('./'+request_path,'rb') as f:
                response_body = f.read()

            response_data = (response_line+response_head+'\r\n').encode() + response_body

            client.send(response_data)
        finally:
            client.close()


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




python高级-socket和web相关_第18张图片

 python高级-socket和web相关_第19张图片

6.面向对象多任务

import multiprocessing
import socket


class server_start(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]} 端口连接成功")

            p = multiprocessing.Process(target=self.task,args=(client,))
            p.start()
        self.server.close()

    def task(self,client):
        request_data = client.recv(1024).decode('utf-8')
        if len(request_data) == 0:
            client.close()
        else:
            request_path = request_data.split(' ')[1]
            print("请求地址是: ",request_path)

            print("request:  ",request_path)

            if request_path == '/':
                request_path = 'index1.html'

            try:
                with open('./'+request_path,'rb') as f:
                    file_con = f.read()
            except Exception as e:
                response_line = "HTTP/1.1 404 NOT FOUND\r\n"
                response_head = "Server: PSWS1.1\r\n"
                with open('./err.html','rb') as f:
                    error_data = f.read()

                response_data = (response_line+response_head+'\r\n').encode('utf-8') + error_data

                client.send(response_data)

            else:
                response_line = "HTTP/1.1 200 OK\r\n"
                response_head = "Server: PSWS1.1\r\n"
                with open('./'+request_path,'rb') as f:
                    response_body = f.read()

                response_data = (response_line+response_head+'\r\n').encode() + response_body

                client.send(response_data)
            finally:
                client.close()


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

python高级-socket和web相关_第20张图片


结语

点赞

你可能感兴趣的:(服务器运维,python,服务器,tcp/ip,python,运维,ide)