摘要:套接字有兩種或者稱為有兩個種族分別是基于文件型的和基于網(wǎng)絡型的。大部分網(wǎng)絡設備的都是。不會發(fā)生黏包,用戶數(shù)據(jù)報協(xié)議是無連接的,面向消息的,提供高效率服務。即面向消息的通信是有消息保護邊界的。
軟件開發(fā)的架構(gòu)
我們了解的涉及到兩個程序之間通訊的應用大致可以分為兩種:
第一種是應用類:qq、微信、網(wǎng)盤、優(yōu)酷這一類是屬于需要安裝的桌面應用
第二種是web類:比如百度、知乎、博客園等使用瀏覽器訪問就可以直接使用的應用
這些應用的本質(zhì)其實都是兩個程序之間的通訊。而這兩個分類又對應了兩個軟件開發(fā)的架構(gòu)~
1.C/S架構(gòu)C/S即:Client與Server ,中文意思:客戶端與服務器端架構(gòu),這種架構(gòu)也是從用戶層面(也可以是物理層面)來劃分的。
這里的客戶端一般泛指客戶端應用程序EXE,程序需要先安裝后,才能運行在用戶的電腦上,對用戶的電腦操作系統(tǒng)環(huán)境依賴較大。
B/S即:Browser與Server,中文意思:瀏覽器端與服務器端架構(gòu),這種架構(gòu)是從用戶層面來劃分的。
Browser瀏覽器,其實也是一種Client客戶端,只是這個客戶端不需要大家去安裝什么應用程序,只需在瀏覽器上通過HTTP請求服務器端相關(guān)的資源(網(wǎng)頁資源),客戶端Browser瀏覽器就能進行增刪改查。
網(wǎng)絡基礎
一個程序如何在網(wǎng)絡上找到另一個程序?首先,程序必須要啟動,其次,必須有這臺機器的地址,我們都知道我們?nèi)说牡刂反蟾啪褪菄沂∈袇^(qū)街道樓門牌號這樣字。那么每一臺聯(lián)網(wǎng)的機器在網(wǎng)絡上也有自己的地址,它的地址是怎么表示的呢?
就是使用一串數(shù)字來表示的,例如:100.4.5.6
1.什么是ip地址?
IP地址是指互聯(lián)網(wǎng)協(xié)議地址(英語:Internet Protocol Address,又譯為網(wǎng)際協(xié)議地址),是IP Address的縮寫。IP地址是IP協(xié)議提供的一種統(tǒng)一的地址格式,它為互聯(lián)網(wǎng)上的每一個網(wǎng)絡和每一臺主機分配一個邏輯地址,以此來屏蔽物理地址的差異。 IP地址是一個32位的二進制數(shù),通常被分割為4個“8位二進制數(shù)”(也就是4個字節(jié))。IP地址通常用“點分十進制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之間的十進制整數(shù)。例:點分十進IP地址(100.4.5.6),實際上是32位二進制數(shù)(01100100.00000100.00000101.00000110)。
2.什么是端口
"端口"是英文port的意譯,可以認為是設備與外界通訊交流的出口。
因此ip地址精確到具體的一臺電腦,而端口精確到具體的程序。
3.osi七層模型
socket概念 socket層 理解socketSocket是應用層與TCP/IP協(xié)議族通信的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把復雜的TCP/IP協(xié)議族隱藏在Socket接口后面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數(shù)據(jù),以符合指定的協(xié)議。
其實站在你的角度上看,socket就是一個模塊。我們通過調(diào)用模塊中已經(jīng)實現(xiàn)的方法建立兩個進程之間的連接和通信。 也有人將socket說成ip+port,因為ip是用來標識互聯(lián)網(wǎng)中的一臺主機的位置,而port是用來標識這臺機器上的一個應用程序。 所以我們只要確立了ip和port就能找到一個應用程序,并且使用socket模塊來與之通信。套接字(socket)的發(fā)展史
套接字起源于 20 世紀 70 年代加利福尼亞大學伯克利分校版本的 Unix,即人們所說的 BSD Unix。 因此,有時人們也把套接字稱為“伯克利套接字”或“BSD 套接字”。一開始,套接字被設計用在同 一臺主機上多個應用程序之間的通訊。這也被稱進程間通訊,或 IPC。套接字有兩種(或者稱為有兩個種族),分別是基于文件型的和基于網(wǎng)絡型的。
1.基于文件類型的套接字家族
套接字家族的名字:AF_UNIX
unix一切皆文件,基于文件的套接字調(diào)用的就是底層的文件系統(tǒng)來取數(shù)據(jù),兩個套接字進程運行在同一機器,可以通過訪問同一個文件系統(tǒng)間接完成通信
2.基于網(wǎng)絡類型的套接字家族
套接字家族的名字:AF_INET
(還有AF_INET6被用于ipv6,還有一些其他的地址家族,不過,他們要么是只用于某個平臺,要么就是已經(jīng)被廢棄,或者是很少被使用,或者是根本沒有實現(xiàn),所有地址家族中,AF_INET是使用最廣泛的一個,python支持很多種地址家族,但是由于我們只關(guān)心網(wǎng)絡編程,所以大部分時候我么只使用AF_INET)
tcp協(xié)議和udp協(xié)議TCP(Transmission Control Protocol)可靠的、面向連接的協(xié)議(eg:打電話)、傳輸效率低全雙工通信(發(fā)送緩存&接收緩存)、面向字節(jié)流。使用TCP的應用:Web瀏覽器;電子郵件、文件傳輸程序。
UDP(User Datagram Protocol)不可靠的、無連接的服務,傳輸效率高(發(fā)送前時延小),一對一、一對多、多對一、多對多、面向報文,盡最大努力服務,無擁塞控制。使用UDP的應用:域名系統(tǒng) (DNS);視頻流;IP語音(VoIP)。
tcp是基于鏈接的,必須先啟動服務端,然后再啟動客戶端去鏈接服務端
1.server端
import socket sk = socket.socket() sk.bind(("127.0.0.1",8898)) #把地址綁定到套接字 sk.listen() #監(jiān)聽鏈接 conn,addr = sk.accept() #接受客戶端鏈接 ret = conn.recv(1024) #接收客戶端信息 print(ret) #打印客戶端信息 conn.send(b"hi") #向客戶端發(fā)送信息 conn.close() #關(guān)閉客戶端套接字 sk.close() #關(guān)閉服務器套接字(可選)
2.客戶端
import socket sk = socket.socket() # 創(chuàng)建客戶套接字 sk.connect(("127.0.0.1",8898)) # 嘗試連接服務器 sk.send(b"hello!") ret = sk.recv(1024) # 對話(發(fā)送/接收) print(ret) sk.close() # 關(guān)閉客戶套接字
3.解決問題,在重啟服務端時可能會遇到
#加入一條socket配置,重用ip和端口 import socket from socket import SOL_SOCKET,SO_REUSEADDR sk = socket.socket() sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加 sk.bind(("127.0.0.1",8898)) #把地址綁定到套接字 sk.listen() #監(jiān)聽鏈接 conn,addr = sk.accept() #接受客戶端鏈接 ret = conn.recv(1024) #接收客戶端信息 print(ret) #打印客戶端信息 conn.send(b"hi") #向客戶端發(fā)送信息 conn.close() #關(guān)閉客戶端套接字 sk.close() #關(guān)閉服務器套接字(可選)基于UDP協(xié)議的socket
udp是無鏈接的,啟動服務之后可以直接接受消息,不需要提前建立鏈接
1.server端
import socket udp_sk = socket.socket(type=socket.SOCK_DGRAM) #創(chuàng)建一個服務器的套接字 udp_sk.bind(("127.0.0.1",9000)) #綁定服務器套接字 msg,addr = udp_sk.recvfrom(1024) print(msg) udp_sk.sendto(b"hi",addr) # 對話(接收與發(fā)送) udp_sk.close() # 關(guān)閉服務器套接字
2.client端
import socket ip_port=("127.0.0.1",9000) udp_sk=socket.socket(type=socket.SOCK_DGRAM) udp_sk.sendto(b"hello",ip_port) back_msg,addr=udp_sk.recvfrom(1024) print(back_msg.decode("utf-8"),addr)
3.例如聊天工具:
server端:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket import json ip_port = ("127.0.0.1",8000) sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(ip_port) while True: qq_msg,addr = sk.recvfrom(1024) qq_msg = json.loads(qq_msg.decode("utf-8")) # print(qq_msg) print("來自{name}的消息,消息是:{msg}".format(name=qq_msg["name"], msg=qq_msg["msg"])) info = input(">>>>:") data = { "name":"server", "msg":info } info = json.dumps(data).encode("utf-8") # print(info) sk.sendto(info,addr)
client端:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket import json server_addr = ("127.0.0.1",8000) ck = socket.socket(type=socket.SOCK_DGRAM) while True: msg = input(">>>>>:") k = { "name":"clinet1", "msg":msg } msg = json.dumps(k).encode("utf-8") ck.sendto(msg,server_addr) qq_msg, addr = ck.recvfrom(1024) qq_msg = json.loads(qq_msg.decode("utf-8")) print("來自{name}的消息,消息是:{msg}".format(name=qq_msg["name"],msg=qq_msg["msg"]))
udp是可以并發(fā)的
socket參數(shù)的詳解socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)
創(chuàng)建socket對象的參數(shù)說明:
黏包 TCP協(xié)議中的數(shù)據(jù)傳遞1.tcp協(xié)議的拆包機制
當發(fā)送端緩沖區(qū)的長度大于網(wǎng)卡的MTU時,tcp會將這次發(fā)送的數(shù)據(jù)拆成幾個數(shù)據(jù)包發(fā)送出去。
MTU是Maximum Transmission Unit的縮寫。意思是網(wǎng)絡上傳送的最大數(shù)據(jù)包。MTU的單位是字節(jié)。 大部分網(wǎng)絡設備的MTU都是1500。如果本機的MTU比網(wǎng)關(guān)的MTU大,大的數(shù)據(jù)包就會被拆開來傳送,這樣會產(chǎn)生很多數(shù)據(jù)包碎片,增加丟包率,降低網(wǎng)絡速度。
2.面向流的通信特點和Nagle算法
TCP(transport control protocol,傳輸控制協(xié)議)是面向連接的,面向流的,提供高可靠性服務。
收發(fā)兩端(客戶端和服務器端)都要有一一成對的socket,因此,發(fā)送端為了將多個發(fā)往接收端的包,更有效的發(fā)到對方,使用了優(yōu)化方法(Nagle算法),將多次間隔較小且數(shù)據(jù)量小的數(shù)據(jù),合并成一個大的數(shù)據(jù)塊,然后進行封包。
這樣,接收端,就難于分辨出來了,必須提供科學的拆包機制。 即面向流的通信是無消息保護邊界的。
對于空消息:tcp是基于數(shù)據(jù)流的,于是收發(fā)的消息不能為空,這就需要在客戶端和服務端都添加空消息的處理機制,防止程序卡住,而udp是基于數(shù)據(jù)報的,即便是你輸入的是空內(nèi)容(直接回車),也可以被發(fā)送,udp協(xié)議會幫你封裝上消息頭發(fā)送過去。
可靠黏包的tcp協(xié)議:tcp的協(xié)議數(shù)據(jù)不會丟,沒有收完包,下次接收,會繼續(xù)上次繼續(xù)接收,己端總是在收到ack時才會清除緩沖區(qū)內(nèi)容。數(shù)據(jù)是可靠的,但是會粘包。
基于tcp協(xié)議特點的黏包現(xiàn)象成因
4.socket數(shù)據(jù)傳輸過程中的用戶態(tài)與內(nèi)核態(tài)說明
發(fā)送端可以是一K一K地發(fā)送數(shù)據(jù),而接收端的應用程序可以兩K兩K地提走數(shù)據(jù),當然也有可能一次提走3K或6K數(shù)據(jù),或者一次只提走幾個字節(jié)的數(shù)據(jù)。 也就是說,應用程序所看到的數(shù)據(jù)是一個整體,或說是一個流(stream),一條消息有多少字節(jié)對應用程序是不可見的,因此TCP協(xié)議是面向流的協(xié)議,這也是容易出現(xiàn)粘包問題的原因。 而UDP是面向消息的協(xié)議,每個UDP段都是一條消息,應用程序必須以消息為單位提取數(shù)據(jù),不能一次提取任意字節(jié)的數(shù)據(jù),這一點和TCP是很不同的。 怎樣定義消息呢?可以認為對方一次性write/send的數(shù)據(jù)為一個消息,需要明白的是當對方send一條信息的時候,無論底層怎樣分段分片,TCP協(xié)議層會把構(gòu)成整條消息的數(shù)據(jù)段排序完成后才呈現(xiàn)在內(nèi)核緩沖區(qū)。
例如基于tcp的套接字客戶端往服務端上傳文件,發(fā)送時文件內(nèi)容是按照一段一段的字節(jié)流發(fā)送的,在接收方看了,根本不知道該文件的字節(jié)流從何處開始,在何處結(jié)束。
此外,發(fā)送方引起的粘包是由TCP協(xié)議本身造成的,TCP為提高傳輸效率,發(fā)送方往往要收集到足夠多的數(shù)據(jù)后才發(fā)送一個TCP段。若連續(xù)幾次需要send的數(shù)據(jù)都很少,通常TCP會根據(jù)優(yōu)化算法把這些數(shù)據(jù)合成一個TCP段后一次發(fā)送出去,這樣接收方就收到了粘包數(shù)據(jù)。
UDP(user datagram protocol,用戶數(shù)據(jù)報協(xié)議)是無連接的,面向消息的,提供高效率服務。 不會使用塊的合并優(yōu)化算法,, 由于UDP支持的是一對多的模式,所以接收端的skbuff(套接字緩沖區(qū))采用了鏈式結(jié)構(gòu)來記錄每一個到達的UDP包,在每個UDP包中就有了消息頭(消息來源地址,端口等信息),這樣,對于接收端來說,就容易進行區(qū)分處理了。 即面向消息的通信是有消息保護邊界的。 對于空消息:tcp是基于數(shù)據(jù)流的,于是收發(fā)的消息不能為空,這就需要在客戶端和服務端都添加空消息的處理機制,防止程序卡住,而udp是基于數(shù)據(jù)報的,即便是你輸入的是空內(nèi)容(直接回車),也可以被發(fā)送,udp協(xié)議會幫你封裝上消息頭發(fā)送過去。 不可靠不黏包的udp協(xié)議:udp的recvfrom是阻塞的,一個recvfrom(x)必須對唯一一個sendinto(y),收完了x個字節(jié)的數(shù)據(jù)就算完成,若是y;x數(shù)據(jù)就丟失,這意味著udp根本不會粘包,但是會丟數(shù)據(jù),不可靠。
udp和tcp一次發(fā)送數(shù)據(jù)長度的限制:
用UDP協(xié)議發(fā)送時,用sendto函數(shù)最大能發(fā)送數(shù)據(jù)的長度為:65535- IP頭(20) – UDP頭(8)=65507字節(jié)。用sendto函數(shù)發(fā)送數(shù)據(jù)時,如果發(fā)送數(shù)據(jù)長度大于該值,則函數(shù)會返回錯誤。(丟棄這個包,不進行發(fā)送) 用TCP協(xié)議發(fā)送時,由于TCP是數(shù)據(jù)流協(xié)議,因此不存在包大小的限制(暫不考慮緩沖區(qū)的大?。?,這是指在用send函數(shù)時,數(shù)據(jù)長度參數(shù)不受限制。而實際上,所指定的這段數(shù)據(jù)并不一定會一次性發(fā)送出去,如果這段數(shù)據(jù)比較長,會被分段發(fā)送,如果比較短,可能會等待和下一次數(shù)據(jù)一起發(fā)送。
黏包現(xiàn)象只發(fā)生在tcp協(xié)議中:
1.從表面上看,黏包問題主要是因為發(fā)送方和接收方的緩存機制、tcp協(xié)議面向流通信的特點。
2.實際上,主要還是因為接收方不知道消息之間的界限,不知道一次性提取多少字節(jié)的數(shù)據(jù)所造成的。
struct模塊
該模塊可以把一個類型,如數(shù)字,轉(zhuǎn)成固定長度的bytes
import json,struct #假設通過客戶端上傳1T:1073741824000的文件a.txt #為避免粘包,必須自定制報頭 header={"file_size":1073741824000,"file_name":"/a/b/c/d/e/a.txt","md5":"8f6fbf8347faa4924a76856701edb0f3"} #1T數(shù)據(jù),文件路徑和md5值 #為了該報頭能傳送,需要序列化并且轉(zhuǎn)為bytes head_bytes=bytes(json.dumps(header),encoding="utf-8") #序列化并轉(zhuǎn)成bytes,用于傳輸 #為了讓客戶端知道報頭的長度,用struck將報頭長度這個數(shù)字轉(zhuǎn)成固定長度:4個字節(jié) head_len_bytes=struct.pack("i",len(head_bytes)) #這4個字節(jié)里只包含了一個數(shù)字,該數(shù)字是報頭的長度 #客戶端開始發(fā)送 conn.send(head_len_bytes) #先發(fā)報頭的長度,4個bytes conn.send(head_bytes) #再發(fā)報頭的字節(jié)格式 conn.sendall(文件內(nèi)容) #然后發(fā)真實內(nèi)容的字節(jié)格式 #服務端開始接收 head_len_bytes=s.recv(4) #先收報頭4個bytes,得到報頭長度的字節(jié)格式 x=struct.unpack("i",head_len_bytes)[0] #提取報頭的長度 head_bytes=s.recv(x) #按照報頭長度x,收取報頭的bytes格式 header=json.loads(json.dumps(header)) #提取報頭 #最后根據(jù)報頭的內(nèi)容提取真實的數(shù)據(jù),比如 real_data_len=s.recv(header["file_size"]) s.recv(real_data_len)
1.使用struct解決黏包
可以把報頭做成字典,字典里包含將要發(fā)送的真實數(shù)據(jù)的詳細信息,然后json序列化,然后用struck將序列化后的數(shù)據(jù)長度打包成4個字節(jié)(4個自己足夠用了)
1.發(fā)送
def mysend(self,file_dic): bytes_dic = json.dumps(file_dic).encode("utf-8") len_dic = struct.pack("i", len(bytes_dic)) self.request.send(len_dic) self.request.send(bytes_dic)
2.接收
def myrecv(self): dic_len = self.request.recv(4) dic_len = struct.unpack("i", dic_len)[0] dic = self.request.recv(dic_len).decode("utf-8") dic = json.loads(dic) return dicsocket的更多方法
服務端套接字函數(shù) s.bind() 綁定(主機,端口號)到套接字 s.listen() 開始TCP監(jiān)聽 s.accept() 被動接受TCP客戶的連接,(阻塞式)等待連接的到來 客戶端套接字函數(shù) s.connect() 主動初始化TCP服務器連接 s.connect_ex() connect()函數(shù)的擴展版本,出錯時返回出錯碼,而不是拋出異常 公共用途的套接字函數(shù) s.recv() 接收TCP數(shù)據(jù) s.send() 發(fā)送TCP數(shù)據(jù) s.sendall() 發(fā)送TCP數(shù)據(jù) s.recvfrom() 接收UDP數(shù)據(jù) s.sendto() 發(fā)送UDP數(shù)據(jù) s.getpeername() 連接到當前套接字的遠端的地址 s.getsockname() 當前套接字的地址 s.getsockopt() 返回指定套接字的參數(shù) s.setsockopt() 設置指定套接字的參數(shù) s.close() 關(guān)閉套接字 面向鎖的套接字方法 s.setblocking() 設置套接字的阻塞與非阻塞模式 s.settimeout() 設置阻塞套接字操作的超時時間 s.gettimeout() 得到阻塞套接字操作的超時時間 面向文件的套接字的函數(shù) s.fileno() 套接字的文件描述符 s.makefile() 創(chuàng)建一個與該套接字相關(guān)的文件
send和sendall方法:
官方文檔對socket模塊下的socket.send()和socket.sendall()解釋如下: socket.send(string[, flags]) Send data to the socket. The socket must be connected to a remote socket. The optional flags argument has the same meaning as for recv() above. Returns the number of bytes sent. Applications are responsible for checking that all data has been sent; if only some of the data was transmitted, the application needs to attempt delivery of the remaining data. send()的返回值是發(fā)送的字節(jié)數(shù)量,這個數(shù)量值可能小于要發(fā)送的string的字節(jié)數(shù),也就是說可能無法發(fā)送string中所有的數(shù)據(jù)。如果有錯誤則會拋出異常。 – socket.sendall(string[, flags]) Send data to the socket. The socket must be connected to a remote socket. The optional flags argument has the same meaning as for recv() above. Unlike send(), this method continues to send data from string until either all data has been sent or an error occurs. None is returned on success. On error, an exception is raised, and there is no way to determine how much data, if any, was successfully sent. 嘗試發(fā)送string的所有數(shù)據(jù),成功則返回None,失敗則拋出異常。 故,下面兩段代碼是等價的: #sock.sendall("Hello world ") #buffer = "Hello world " #while buffer: # bytes = sock.send(buffer) # buffer = buffer[bytes:]socketserver
1.server端
import socketserver class Myserver(socketserver.BaseRequestHandler): def handle(self): self.data = self.request.recv(1024).strip() print("{} wrote:".format(self.client_address[0])) print(self.data) self.request.sendall(self.data.upper()) if __name__ == "__main__": HOST, PORT = "127.0.0.1", 9999 # 設置allow_reuse_address允許服務器重用地址 socketserver.TCPServer.allow_reuse_address = True # 創(chuàng)建一個server, 將服務地址綁定到127.0.0.1:9999 server = socketserver.TCPServer((HOST, PORT),Myserver) # 讓server永遠運行下去,除非強制停止程序 server.serve_forever() server端
2.客戶端
import socket HOST, PORT = "127.0.0.1", 9999 data = "hello" # 創(chuàng)建一個socket鏈接,SOCK_STREAM代表使用TCP協(xié)議 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((HOST, PORT)) # 鏈接到客戶端 sock.sendall(bytes(data + " ", "utf-8")) # 向服務端發(fā)送數(shù)據(jù) received = str(sock.recv(1024), "utf-8")# 從服務端接收數(shù)據(jù) print("Sent: {}".format(data)) print("Received: {}".format(received))
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/42113.html
摘要:網(wǎng)絡編程學習本文主要介紹網(wǎng)絡通信,以及的通信例子網(wǎng)絡通信是嵌套字的意思,可以理解為與們間的在線會話。關(guān)于通信可以看這里簡單理解多線程下開啟一個對于服務端,需要做件事情開啟設置配置綁定端口幀監(jiān)聽,收發(fā)包多線程關(guān)于報錯模塊提供個函數(shù)。 http://homeway.me/ python網(wǎng)絡編程學習 本文主要介紹socket網(wǎng)絡通信,以及python的socket通信例子 ...
摘要:在任何類型的通信開始之前,網(wǎng)絡應用程序必須創(chuàng)建套接字。基于文件的套接字,家族名又名基于網(wǎng)絡的套接字,家族名在和后續(xù)的版本中,支持的套接字有,,,。中的網(wǎng)絡編程在中主要是用模塊來實現(xiàn)基于套接字的網(wǎng)絡通信。 python學習記錄--網(wǎng)絡編程 1、套接字介紹 一臺機器上的不同進程之間進行通信可以利用隊列,管道等,但是不同機器之間的進程進行通信用隊列是不行的,解決這個問題就是網(wǎng)絡套接字。 套接...
摘要:中卻發(fā)生了異常。接收數(shù)據(jù)使用函數(shù)接收數(shù)據(jù)在中返回的是對象,在中返回的是。注意函數(shù)返回的數(shù)據(jù)長度是小于或者等于參數(shù)指定的長度的,要接收到指定長度的數(shù)據(jù),需要循環(huán)接收數(shù)據(jù)。當一個被回收時會自動關(guān)閉,但是不要依賴這種機制,不需要時就主動的。 本文介紹使用Python進行Socket網(wǎng)絡編程,假設讀者已經(jīng)具備了基本的網(wǎng)絡編程知識和Python的基本語法知識,本文中的代碼如果沒有說明則都是運行在...
摘要:創(chuàng)建創(chuàng)建通信接受套接字的數(shù)據(jù),與類似,但返回值是。發(fā)送數(shù)據(jù),將數(shù)據(jù)發(fā)送到,形式為,指定遠程地址發(fā)送,返回值是發(fā)送的字節(jié)數(shù)發(fā)送的報文是類型,發(fā)送的報文是類型,在發(fā)送前要記得編碼。 UDP 和 TCP 的區(qū)別 ? TCP UDP 連接性 面向連接 面向無連接 傳輸可靠性 可靠 不可靠 傳輸模式 流 數(shù)據(jù)報 應用場景 傳輸大量的數(shù)據(jù) 少量數(shù)據(jù) 速度 慢 快 T...
摘要:的明確目標是成為標準網(wǎng)絡協(xié)議棧的一部分,之后進入內(nèi)核。實現(xiàn)端測試消息已發(fā)送端正在轉(zhuǎn)發(fā)端輸出結(jié)果已發(fā)送已發(fā)送已發(fā)送正在轉(zhuǎn)發(fā)正在轉(zhuǎn)發(fā)正在轉(zhuǎn)發(fā)測試消息測試消息測試消息 簡介 ZMQ (以下 ZeroMQ 簡稱 ZMQ)是一個簡單好用的傳輸層,像框架一樣的一個 socket library,他使得 Socket 編程更加簡單、簡潔和性能更高。是一個消息處理隊列庫,可在多個線程、內(nèi)核和主機盒之間...
摘要:提供了兩個基本的模塊,它提供了標準的。類型套接字格式使用給定的地址族套接字類型協(xié)議編號默認為來創(chuàng)建套接字。函數(shù)注意點發(fā)送數(shù)據(jù)時,已建立好連接,所以不需要指定地址。是面向無連接,每次發(fā)送要指定是發(fā)給誰。 Python 提供了兩個基本的 socket 模塊 Socket,它提供了標準的 BSD Sockets API。 SocketServer,它提供了服務器中心類,可以簡化網(wǎng)絡服務器的...
閱讀 985·2021-11-22 09:34
閱讀 2168·2021-11-11 16:54
閱讀 2206·2021-09-27 14:00
閱讀 950·2019-08-30 15:55
閱讀 1537·2019-08-29 12:46
閱讀 610·2019-08-26 18:42
閱讀 648·2019-08-26 13:31
閱讀 3191·2019-08-26 11:52