一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語(yǔ)言編程技術(shù)及教程分享平臺(tái)!
分類(lèi)導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - 最基礎(chǔ)的Python的socket編程入門(mén)教程

最基礎(chǔ)的Python的socket編程入門(mén)教程

2020-06-11 09:53愚安 Python

這篇文章主要介紹了最基礎(chǔ)的Python的socket編程入門(mén)教程,包括最基本的發(fā)送和接受信息等內(nèi)容,需要的朋友可以參考下

本文介紹使用Python進(jìn)行Socket網(wǎng)絡(luò)編程,假設(shè)讀者已經(jīng)具備了基本的網(wǎng)絡(luò)編程知識(shí)和Python的基本語(yǔ)法知識(shí),本文中的代碼如果沒(méi)有說(shuō)明則都是運(yùn)行在Python 3.4下。

Python的socket功能封裝在socket庫(kù)中,要使用socket,記得先import socket,socket庫(kù)的詳細(xì)介紹參見(jiàn)官方文檔。
創(chuàng)建Socket

首先創(chuàng)建一個(gè)socket,使用socket庫(kù)中得socket函數(shù)創(chuàng)建。

?
1
import socket
?
1
2
# create an INET, STREAM socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

例子中創(chuàng)建了一個(gè)TCP socket,socket.socket函數(shù)的前兩個(gè)參數(shù)的默認(rèn)值是socket.AF_INET和socket.SOCK_STREAM,創(chuàng)建TCP socket時(shí)可以直接寫(xiě)成socket.socket()。
連接服務(wù)器

使用socket的connect函數(shù)連接到服務(wù)器,以下幾種參數(shù)都是合法的。

?
1
2
3
s.connect(('localhost', 8000))
s.connect(('127.0.0.1', 8000))
s.connect(('www.baidu.com', 80))

發(fā)送數(shù)據(jù)

發(fā)送數(shù)據(jù)有兩個(gè)方法send和sendall,send不能保證所有的數(shù)據(jù)都發(fā)送完了,它會(huì)返回已發(fā)送數(shù)據(jù)的長(zhǎng)度,程序要循環(huán)發(fā)送數(shù)據(jù)直到所有數(shù)據(jù)都已發(fā)送完畢。

?
1
2
3
4
5
6
7
8
def mysend(s, msg):
  total_len = len(msg)
  total_sent = 0
  while total_sent < total_len:
    sent = s.send(msg[total_sent:])
    if sent == 0:
      raise RuntimeError("socket connection broken")
    total_sent += sent

sendall能夠保證所有的數(shù)據(jù)都已發(fā)送完畢,除非發(fā)送過(guò)程中出現(xiàn)了錯(cuò)誤,它實(shí)際上也是循環(huán)發(fā)送數(shù)據(jù)直到所有數(shù)據(jù)發(fā)送完成。

這里還要講一個(gè)需要特別注意的地方,從一個(gè)例子開(kāi)始吧:

?
1
2
3
4
import socket
s = socket.socket()
s.connect(('www.baidu.com', 80))
s.sendall('test')

都是上面講過(guò)的東西,沒(méi)什么特別的,分別在Python 2和Python 3中執(zhí)行以上的代碼,結(jié)果是:

?
1
2
3
4
5
# Python 2.7
>>> import socket
>>> s = socket.socket()
>>> s.connect(('www.baidu.com', 80))
>>> s.sendall('test')

Python 2中執(zhí)行成功。

?
1
2
3
4
5
6
7
8
# Python 3.4
>>> import socket
>>> s = socket.socket()
>>> s.connect(('www.baidu.com', 80))
>>> s.sendall('test')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface

Python 3中卻發(fā)生了異常。

同樣的代碼換個(gè)環(huán)境卻不能執(zhí)行了,我沒(méi)有寫(xiě)錯(cuò)呀,怒砸電腦。好吧,你確實(shí)沒(méi)寫(xiě)錯(cuò),是環(huán)境變了,導(dǎo)致這個(gè)結(jié)果的變化請(qǐng)移步官方的說(shuō)明。
接收數(shù)據(jù)

使用recv函數(shù)接收數(shù)據(jù):

?
1
data = s.recv(4096)

在Python 3中返回的是bytes對(duì)象,在Python 2中返回的是string。注意函數(shù)返回的數(shù)據(jù)長(zhǎng)度是小于或者等于參數(shù)指定的長(zhǎng)度的,要接收到指定長(zhǎng)度的數(shù)據(jù),需要循環(huán)接收數(shù)據(jù)。

?
1
2
3
4
5
6
7
8
9
10
def myreceive(s, msglen):
  chunks = []
  bytes_recd = 0
  while bytes_recd < msglen:
    chunk = s.recv(min(msglen - bytes_recd, 2048))
    if chunk == b'':
      raise RuntimeError("socket connection broken")
    chunks.append(chunk)
    bytes_recd = bytes_recd + len(chunk)
  return b''.join(chunks)

關(guān)閉連接

當(dāng)連接不再需要時(shí)可以使用close關(guān)閉socket連接,關(guān)閉后的連接不能再進(jìn)行任何操作。當(dāng)一個(gè)socket被回收時(shí)會(huì)自動(dòng)關(guān)閉,但是不要依賴(lài)這種機(jī)制,不需要socket時(shí)就主動(dòng)的close。
服務(wù)端

服務(wù)端程序執(zhí)行的步驟:
1. 創(chuàng)建服務(wù)端socket
1. 將服務(wù)端socket綁定到指定的地址和端口
1. 監(jiān)聽(tīng)連接
1. 接受客戶(hù)端連接
1. 處理客戶(hù)端的數(shù)據(jù)
1. 關(guān)閉客戶(hù)端連接

一個(gè)簡(jiǎn)單的echo server示例:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import socket
 
HOST = ''
PORT = 10022
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(10)
conn, addr = s.accept()
while True:
  data = conn.recv(1024)
  if not data:
    break
  conn.sendall(data)
conn.close()

客戶(hù)端程序:

?
1
2
3
4
5
6
7
8
9
10
11
import socket
 
HOST = 'localhost'
PORT = 10022
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'hello socket')
data = s.recv(1024)
print('Received', repr(data))
s.close()

錯(cuò)誤處理

socket處理過(guò)程中發(fā)生錯(cuò)誤會(huì)拋出異常,socket相關(guān)的異常有:

  • - socket.error
  • - socket.herror
  • - socket.gaierror
  • - socket.timeout
?
1
2
3
4
5
6
7
8
9
10
11
import socket
 
HOST = None
PORT = 10022
 
try:
  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.bind((HOST, PORT))
  s.listen(10)
except: socket.error as msg:
  print(msg)

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久国产热视频99rev6 | 国产一区二区免费福利片 | 精品午夜寂寞影院在线观看 | 236宅宅2021最新理论 | 亚洲色大成网站www久久九九 | 含羞草传媒网站免费进入欢迎 | 女人把扒开给男人爽 | 日本人和黑人一级纶理片 | 男人午夜剧场 | 国产成人高清亚洲一区91 | 逼逼流水了 | 欧美xxoo做爰猛烈视频 | 精品免费tv久久久久久久 | 紧身裙女教师miad711在线 | 欧美视频一区二区专区 | 欧美男男gaygaysxxx | 国产成人一区二区三区视频免费蜜 | 人成午夜免费大片在线观看 | 国产99页| 国产一区二区三区在线看片 | 国产欧美日韩不卡 | 87影院在线观看视频在线观看 | 性刺激欧美三级在线现看中文 | 疯狂伦交1一6小说 | 三体动漫在线观看免费完整版2022 | 女人把私密部位张开让男人桶 | 青青草综合网 | 色淫阁小说 | 4hu影院永久在线播放 | 奇米狠狠色 | 免费操比视频 | 国产资源一区 | 黑人异族日本人hd | 欧美a级v片在线观看一区 | 激情小说色图 | 国产在线看片护士免费视频 | 亚洲成年男人的天堂网 | 青草视频网址 | 99看视频 | 黄片毛片 | 韩国漂亮美女三级在线观看 |