09-Python-Socket编程

一、Python-Socket编程

1.1、弄懂HTTP、Socket、TCP这几个概念

  什么是HTTP协议?浏览器的本质就是一个socket客户端遵循HTTP协议,HTTP协议的本质:通过\r\n分割的规范+请求响应之后断开连接。HTTP协议是建立在tcp之上的,HTTP是一种规范,它规定了发送数据的数据格式,这个数据格式是通过\r\n进行分割的,请求头与请求体也是通过2个\r\n分割的。响应的时候,响应头与响应体也是通过\r\n分割,并且规定了请求已响应就会断开连接,是一种短连接,无状态。

  什么是socketsocket是应用层与tcp/ip协议族通信的中间软件的抽象层,他是一组接口。在设计模式中,socket其实就是一个门面模式,他把复杂的TCP/IP协议族隐藏在socket接口后面,对用户来说一组接口就是全部。

  什么是TCP?TCP三次握手,四次挥手的流程。三次握手:1客户端先向服务器发送SYN状态码,告诉服务器想要建立连接。2然后服务端向客户端回复ACK+SYN状态码告诉客户端可以连接。3然后客户端回复确认ACK状态码给服务器,建立连接。四次挥手:1客户端向服务器发送FIN+SEQ状态码,告诉服务器想要断开。2然后服务器向客户端回复ACK+SEQ状态码,服务器此时进入close-wait状态,等待连接通道数据传输完毕,传输完毕后。3然后服务器向客户端发送FIN+SEQ状态码,此时服务器进入最后确认状态。4最后客户端向服务器发送ACK+SEQ状态码,服务器接收到后立即进入close状态,连接断开。

socket套接字抽象层接口:

 

 

 

1.2、socket和server实现通信

import socket


server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#协议
server.bind(('0.0.0.0', 8000)) #地址,端口
server.listen(10)  #监听socket客户端请求
sock, addr = server.accept() #阻塞等待连接请求
#获取从客户端发送的数据
#一次获取1k的数据
data = sock.recv(1024)
print(data.decode("utf8"))
re_data = input()  #输入发送给客户端的消息
sock.send(re_data.encode("utf8"))
sock.close() #关闭连接
server.close() #关闭服务器
socket_server
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

client.connect(('127.0.0.1', 8000)) #连接服务端
client.send("lishuntao".encode("utf8"))
data = client.recv(1024)
print (data.decode("utf8"))
client.close()
socket_client 

1.3、socket实现聊天和多用户连接

socket_server:

import socket
import threading


backlog = 10
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('0.0.0.0', 8000))
server.listen(backlog)

def handle_sock(sock, addr):
    while True:
        data = sock.recv(1024)
        if data.decode("utf8") == "Q" or data.decode("utf8") == "q":
            break
        print(data.decode("utf8"))
        re_data = input()
        sock.send(re_data.encode("utf8"))
    sock.close()
    server.close()

while True:
    sock, addr = server.accept()

    #用线程去处理新接收的连接(用户)
    client_thread = threading.Thread(target=handle_sock, args=(sock, addr))
    client_thread.start()

socket_client:

import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
    re_data = input()
    if re_data.upper() == "Q":
        break
    client.send(re_data.encode("utf8"))
    data = client.recv(1024)
    print(data.decode("utf8"))
client.close()

1.4、socket模拟http请求

#requests(封装了urlib) -> urlib(封装了socket) -> socket(封装TCP/UDP协议)
import socket
from urllib.parse import urlparse

def get_url(url):
    #通过socket请求html
    url = urlparse(url)
    host = url.netloc
    path = url.path
    if path == "":
        path = "/"

    #建立socket连接
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # client.setblocking(False)
    client.connect((host, 80)) #阻塞不会消耗cpu

    #不停的询问连接是否建立好, 需要while循环不停的去检查状态
    #做计算任务或者再次发起其他的连接请求

    client.send("GET {} HTTP/1.1\r\nHost:{}\r\nConnection:close\r\n\r\n".format(path, host).encode("utf8"))

    data = b""
    while True:
        d = client.recv(1024)
        if d:
            data += d
        else:
            break

    data = data.decode("utf8")
    html_data = data.split("\r\n\r\n")[1]
    print(html_data)
    client.close()

if __name__ == "__main__":
    url = "https://www.baidu.com/"
    get_url(url)

 

posted @ 2019-12-12 13:33  一知.半解  阅读(408)  评论(0编辑  收藏  举报