Python Socket编程

系统整理 Python Socket 编程的基础概念和代码实践,覆盖客户端、服务端和网络通信流程。

Socker编程,就是面向(域名,端口)构成的Socket进行编程

服务端

socket()
bind()
listen()
accept()
read() 或 recv()等
write() 或 send()等
close()

客户端

socket()
connect()
write() 或 send()等
read() 或 recv()等
close()

话不多说直接上代码

首先模拟一下客户端,对博客服务器进行测试

#Socket client example in python

import socket   #for sockets
import sys  #for exit

#create an INET, STREAMing socket
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
    print('Failed to create socket')
    sys.exit()

print('Socket Created')

host = '47.102.193.146'
port = 80

try:
    remote_ip = socket.gethostbyname( host )

except socket.gaierror:
    #could not resolve
    print( 'Hostname could not be resolved. Exiting')
    sys.exit()

#Connect to remote server
s.connect((remote_ip , port))

print ('Socket Connected to ' + host + ' on ip ' + remote_ip)

#Send some data to remote server
message = b"GET / HTTP/1.1rnHost: 47.102.193.146rnrn"

try:
    # Set the whole string
    s.sendall(message)
except socket.error:
    # Send failed
    print('Send failed')
    sys.exit()

print ('Message send successfully')

#Now receive data
reply = s.recv(4096)

print (reply)

返回值:

b'HTTP/1.1 200 OKrnServer: nginxrnDate: Fri, 12 Apr 2024 04:51:25 GMTrnContent-Type: text/html; charset=UTF-8rnTransfer-Encoding: chunkedrnConnection: keep-alivernVary: Accept-EncodingrnLink: <https://blog.awz66661.top/index.php/wp-json/>; rel="https://api.w.org/"rnrn42darn<!DOCTYPE html>rn<html lang="zh-cn" xmlns="http://www.w3.org/1999/html" class="personal">rn<head>rn    <meta name="theme-color" content="#ffffff"/>rn    <meta charset="UTF-8"/>rn    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">rnt        <title>awz66661'blogxefxbcx8dxe4xb8x8exe4xbdxa0xe5x85xb1xe4xbaxabxe7xbex8exe5xa5xbdxe7x94x9fxe6xb4xbb</title>rn        <meta name="keywords" content="desitinationxe4xb8xbbxe9xa2x98"/>rn        <meta name="description" content="xe4xb8x80xe6xacxbexe8x87xaaxe7x94xb1xe7x9ax84xe5x8dx9axe5xaexa2xe4xb8xbbxe9xa2x98"/>rntttt<meta name='robots' content='max-image-preview:large' />n<link rel='stylesheet' id='popularis-extra-css' href='https://blog.awz66661.top/wp-content/plugins/popularis-extra/assets/css/style.css?ver=1.2.3' type='text/css' media='all' />n<link rel='stylesheet' id='main-styles-css' href='https://blog.awz66661.top/wp-content/themes/theme-document/style.css?ver=1712718461' type='text/css' media='all' />n<style id='main-styles-inline-css' type='text/css'>n.personal{--theme-color:#3eaf7c;--theme-header-bg-color:#fff;--theme-header-font-color:#262626;--theme-sub-menu-bg-color:#fff;--theme-sub-menu-font-color:rgba(0,0,0,0.65);--theme-header-border-color:#e1e1e1;--theme-header-shadow-color:hsl(230deg 68% 14% / 1%);--theme-footer-bg-color: transparent;--theme-footer-font-color: #262626;}n</style>n<link rel='stylesheet' id='swiper_self-css' href='https://blog.awz66661.top/wp-content/themes/theme-document/common/swiper/swiper.css?ver=1712718464' type='text/css' media='all' />n<link rel='stylesheet' id='swiper-css' href='https://blog.awz66661.top/wp-content/plugins/elementor/assets/lib/swiper/v8/css/swiper.min.css?ver=8.4.5' type='text/css' media='all' />n<script type="text/javascript" src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.min.js?ver=6.5.2" id="jquerys-js"></script>n<script type="text/javascript" src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/enquire.js/2.1.6/enquire.js?ver=6.5.2" id="enquire-js"></script>n<script type="text/javascript" id="main-sub-js-before">n/* <![CDATA[ */nwindow.ROOT="https://blog.awz66661.top/wp-content/themes/theme-document";window.HOME="https://blog.awz66661.top";n/* ]]> */n</script>n<script type="text/javascript" src="https://blog.awz66661.top/wp-content/themes/theme-document/common/inline/main.js?ver=1712718465" id="main-sub-js"></script>n<script type="text/javascript" id="main-js-before">n/* <![CDATA[ */nconst DYNAMIC=0;const IN_HOME=true;n/* ]]> */n</script>n<script type="text/javascript" src="https://blog.awz66661.top/wp-content/themes/theme-document/common/main.js?ver=1712718465" id="main-js"></script>n<script type="text/javascript" src="https://blog.awz66661.top/wp-content/themes/theme-document/common/inline/monitor.js?ver=1712718465" id="main-monitor-js"></script>n<script type="text/javascript" src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/Swiper/8.0.3/swiper-bundle.min.js?ver=6.5.2" id="swiper-js"></script>n<script type="text/javascript" id="main-index-js-before">n/* <![CDATA[ */nconst Auto_load_index=1;const Auto_load_else=1;n/* ]]> */n</script>n<script type="text/javascript" src="https://blog.awz66661.top/wp-content/themes/theme-document/common/inline/index.js?ver=1712718465" id="main-index-js"></script>n<meta name="generator" content="Elementor 3.20.1; features: e_optimized_assets_loading, e_optimized_css_loading, e_font_icon_svg, additional_custom_breakpoints, block_editor_assets_optimize, e_image_loading_optimization; settings: css_print_method-external, google_font-enabled, font_display-swap">n<link rel="icon" href="https://img.awz66661.top/i/wp-content/uploads/2024/04/cropped-image-5-32x32.png" sizes="32x32" />n<link rel="icon" href="https://img.awz66661.top/i/wp-content/uploads/2024/04/cropped-image-5-192x192.png" sizes="192x192" />n<link rel="apple-touch-icon" href="https://img.awz66661.top/i/wp-content/uploads/2024/04/cropped-image-5-180x180.png'

我们再试试服务器端:

import socket
import sys

HOST = ''   # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print ('Socket created')

try:
    s.bind((HOST, PORT))
except socket.error:
    print ('Bind failed.')
    sys.exit()

print ('Socket bind complete')

s.listen(10)
print ('Socket now listening')

# Wait to accept a connection - blocking call
conn, addr = s.accept()

# Display client information
print ('Connected with ' + addr[0] + ':' + str(addr[1]))

# Now keep talking with the client
while 1:
    # Receive data from client
    data = conn.recv(1024)
    if not data:
        break
    conn.sendall(b'Hello, you are connected to the server.')

conn.close()

我们将Socket绑定为本机的8888端口

再用刚刚的Client访问试试?

#Socket client example in python

import socket   #for sockets
import sys  #for exit

#create an INET, STREAMing socket
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
    print('Failed to create socket')
    sys.exit()

print('Socket Created')

host = '127.0.0.1'
port = 8888

try:
    remote_ip = socket.gethostbyname( host )

except socket.gaierror:
    #could not resolve
    print( 'Hostname could not be resolved. Exiting')
    sys.exit()

#Connect to remote server
s.connect((remote_ip , port))

print ('Socket Connected to ' + host + ' on ip ' + remote_ip)

#Send some data to remote server
message = b"GET / HTTP/1.1rnHost: 47.102.193.146rnrn"

try:
    # Set the whole string
    s.sendall(message)
except socket.error:
    # Send failed
    print('Send failed')
    sys.exit()

print ('Message send successfully')

#Now receive data
reply = s.recv(4096)

print (reply)

运行得到:

awz@awz:~/socketProgram$ python3 client.py 
Socket Created
Socket Connected to 127.0.0.1 on ip 127.0.0.1
Message send successfully
b'Hello, you are connected to the server.'

这样就完成了最简单的Socket编程