亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

44網絡編程_socket_TCP

發布時間:2020-06-29 00:31:23 來源:網絡 閱讀:254 作者:chaijowin 欄目:編程語言

?

?

?

目錄

socket,套接字:... 1

TCP編程:... 2

TCP服務器端編程步驟:... 3

群聊程序,TCP實現:... 5

makefile... 7

TCP客戶端編程步驟:... 10

?

?

?

socket,套接字:

py中提供socket.py標準庫,非常底層的接口庫;

socket是一種通用的網絡編程接口;

44網絡編程_socket_TCP

?

協議族:

AFaddress family,用于sock=socket.socket()第一個參數;

AF_NETipv4

AF_NET6ipv6

AF_UNIXunix domain socketwin沒有這個;

?

socket類型:

socket.SOCK_STREAM,面向連接的流套接字,默認值TCP協議,如sock=socket.socket(type=socket.SOCK_STREAMsock=socket.socket())均取默認;

socket.SOCK_DGRAM,無連接的數據報文套接字,UDP協議,如sock=socket.socket(type=socket.SOCK_DGRAM)

?

?

?

TCP編程:

socket編程,需要兩端,一般需要一個服務端server,一個客戶端client

?

C/S模型,C/S編程;

B/SB/S編程,本質上是C/S,是種特殊的C/S,要支持httphtmlh6)、cssjs、聲音、視頻等;只做Bweb前端開發;

?

TCP服務器端編程步驟:

創建socket對象,socket(family=AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None)

綁定ipportbind()方法;ipv4地址為一個二元組('ip',port)

開始監聽,將在指定的ipport上監聽,listen()方法;

獲取用于傳送數據的socket對象:

???????? accept()阻塞等待客戶端建立連接,返回一個新的socket對象和客戶端地址(ipv4為二元組地址,遠程客戶端的地址),如accept() -> (socket object, address info)

???????? recv(bufsize[,flags]),接收數據,使用緩沖區接收數據;

???????? send(bytes),發送數據;

?

生產中編程時不會用這么底層的模塊,當前使用是用于理解socket

?

sock=socket.socket()

ip='127.0.0.1'

port=9999

addr=(ip,port)

sock.bind(addr)

sock.lienten()

conn,addrinfo=sock.accept()

?

conn.recv(bufsize[,flag]),獲取數據,默認是阻塞方式,TCP接收數據

conn.recvfrom(bufsize[,flag]),獲取數據,返回一個二元組(bytes,address)UDP接收數據

conn.recv_into(buffer[,nbytes][,flag]]),獲取到nbytes的數據后,存儲到buffer中;如果nbytes沒有指定或0,將buffer大小的數據存入buffer中;返回接收的字節數

conn.recvfrom_into(buffer[,nbytes[,flags]]),獲取數據,返回一個二元組(bytes,address)buffer中;

conn.send(bytes[,flags])TCP發送數據

conn.sendall(bytes[,flags])TCP發送全部數據,成功返回None本質上調的是send()

conn.sendto(string[,flag],address)UDP發送數據

conn.sendfile(file,offset=0,count=None),發送一個文件直至EOF,使用高性能的ossendfile機制,返回發送的字節數win不支持sendfile,不是普通文件時,用send()發送文件;offset指起始位置;3.5版開始;

?

conn.getpeername(),返回連接套接字的遠程地址,返回值通常是元組(ipaddr,port)

conn.getsockname(),返回套接字自己的地址,通常是元組(ipaddr,port)

conn.setblocking(flag),默認值True阻塞;False0非阻塞,通常將套接字設為非阻塞,非阻塞模式下,如果調用recv()沒有發現任何數據,或調用send()無法立即發送數據,將引起socket.error異常;Set the socket to blocking (flag is true) or non-blocking (false). setblocking(True) is equivalent to settimeout(None);setblocking(False) is equivalent to settimeout(0.0).

conn.settimeout(value),設置套接字操作的超時期,timeout是一個浮點數,單位s,值為None表示沒有超時期;一般,超時期應在剛創建套接字時設置,因為它們可能用于連接的操作,如connect()

conn.setsockopt(level,optname,value),設置套接字選項的值,如緩沖區大小等;具體看help有很多選項,不同OS不同version都不盡相同;

?

例:

sock = socket.socket()?? #步驟1,均取默認,family=AF_NET,type=SOCK_STREAM

?

ip = '192.168.7.144'?? #點分四段表示

port = 9999

addr = (ip, port)

sock.bind(addr)?? #步驟2

?

sock.listen()?? #步驟3

?

# s1 = socket.socket()

# s1.bind(addr)?? #OSError: [WinError 10048] 通常每個套接字地址(協議/網絡地址/端口)只允許使用一次

# s1.listen()

?

time.sleep(3)

logging.info(sock)

?

conn, addrinfo = sock.accept()?? #步驟4

# while True:?? #不能這樣寫,接收進1client請求后,之后的連接請求接收不到,解決:多線程

#???? conn, addrinfo = sock.accept()

?

logging.info('{} {}'.format(conn, addrinfo))

?

for i in range(3):

??? data = conn.recv(1024)

??? logging.info(data)?? #字節碼

??? logging.info(data.decode())?? #字符串

??? msg = 'ask {}'.format(data.decode())?? #要發送字節碼,若用data則拋TypeError異常

??? conn.send(msg.encode())

?

conn.close()

sock.close()

輸出:

2018-08-08-11:28:03?????? Thread info: 13528 MainThread <socket.socket fd=236, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.7.144', 9999)>

2018-08-08-11:28:04?????? Thread info: 13528 MainThread <socket.socket fd=240, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.7.144', 9999), raddr=('192.168.7.144', 7536)> ('192.168.7.144', 7536)

2018-08-08-11:28:47?????? Thread info: 13528 MainThread b'fuck'

2018-08-08-11:28:47?????? Thread info: 13528 MainThread fuck

2018-08-08-11:28:52?????? Thread info: 13528 MainThread b'fuck again'

2018-08-08-11:28:52?????? Thread info: 13528 MainThread fuck again

2018-08-08-11:28:58?????? Thread info: 13528 MainThread b'fuck again again'

2018-08-08-11:28:58?????? Thread info: 13528 MainThread fuck again again

44網絡編程_socket_TCP

44網絡編程_socket_TCP

?

?

群聊程序,TCP實現:

例:

群聊程序:

需求分析:聊天工具CS程序;

服務器應具有的功能:

啟動服務,包括綁定地址端口、監聽;

建立連接,能和多個client建立連接;

接收不同用戶信息;

分發,將接收的某個用戶的信息轉發到已連接的所有client

停止服務;

記錄連接的client

?

class ChatServer:

??? def __init__(self, ip='127.0.0.1', port=9999):?? #生產中用ini文件配置

??????? self.sock = socket.socket()

??????? self.addr = (ip, port)

??????? self.clients = {}

??????? self.event = threading.Event()

?

??? def start(self):

??????? self.sock.bind(self.addr)

??????? self.sock.listen()

??????? threading.Thread(target=self._accept, name='accept').start()

?

??? def stop(self):

??????? for conn in self.clients.values():

??????????? conn.close()

??????? self.sock.close()

??????? self.event.wait(3)?? #TCP資源回收要些時間;UDP很快

??????? self.event.set()

?

??? def _accept(self):

??????? # while True:

??????? while not self.event.is_set():

??? ????????conn, client = self.sock.accept()

??????????? self.clients[client] = conn

??????????? threading.Thread(target=self._recv, args=(conn, client), name='recv').start()

?

??? def _recv(self, conn, client):

??????? # while True:

??????? while not self.event.is_set():

??????????? data = conn.recv(1024)?? #databytecode,此句可能有異常,建議放在try...except

??????????? data = data.strip().decode()?? #datastring

??????????? logging.info(data)

??????????? if data == 'quit':

??????????????? logging.info('...quit')

??????????????? self.clients.pop(client)

??????????????? conn.close()

??????????????? break

??????????? msg = 'ack {}'.format(data)?? #msgstring

??????????? # conn.send(msg.encode())

??????????? for c in self.clients.values():?? #注意此處c不能寫為conn,否則會將上面的conn覆蓋;一般循環次數用一個字符i,有意義的變量用多個字符

??????????????? c.send(msg.encode())?? #send的數據要為bytecode

?

cs = ChatServer()

cs.start()

?

e = threading.Event()

def showthread():

??? while not e.wait(5):

??????? logging.info(threading.enumerate())

# showthread()

# cs.stop()

threading.Thread(target=showthread, daemon=True).start()?? #用于自己監控看,可隨時關閉

?

while True:

??? cmd = input('>>> ').strip()

??? if cmd == 'quit':

??????? cs.stop()

??????? break

?

注:

仍有問題:各種異常處理;client主動退出后server不知道;

?

?

makefile

conn,clientinfo=sock.accept(1024)

f=conn.makefile(mode='r',buffering=None,*,encoding=None,errors=None,newline=None)?? #創建一個與該套接字相關聯的文件對象;

?

高級接口用的是makefile

?

例:

sock = socket.socket()

ip = '127.0.0.1'

port = 9999

addr = (ip,port)

sock.bind(addr)

sock.listen()

?

conn, addrinfo = sock.accept()

f = conn.makefile(mode='rw')

line = f.read(10)?? #等價conn.recv(1024),兩者差不多,makefile在處理字符串上容易些(不用decode()encode()

print(line)

f.write('return your msg:{}'.format(line))? ?#conn.send(msg)

f.flush()

?

?

例,使用makefile循環接收消息:

sock = socket.socket()

ip = '127.0.0.1'

port = 9999

addr = (ip,port)

sock.bind(addr)

sock.listen()

?

event = threading.Event()

?

def accept(sock, event:threading.Event):

??? conn, addrinfo = sock.accept()

??? f = conn.makefile(mode='rw')

??? while True:

??????? line = f.readline()?? #注意此處按行讀取,遇到\n才接收;類似conn.recv(1024)

??????? print(line)

??????? if line.strip() == 'quit':

??????????? break

??????? f.write('return your msg:{}'.format(line))?? #conn.send(msg)

??????? f.flush()

??? f.close()

??? sock.close()

??? event.wait(3)

??? print('end')

??? event.set()

?

threading.Thread(target=accept, args=(sock, event)).start()

while not event.wait(5):

??? print(sock)

?

例,將ChatServer改為makefile

class ChatServer:

??? def __init__(self, ip='127.0.0.1', port=9999):

??????? self.sock = socket.socket()

??????? self.addr = (ip, port)

??????? self.clients = {}

??????? self.event = threading.Event()

?

??? def start(self):

??????? self.sock.bind(self.addr)

??????? self.sock.listen()

??????? threading.Thread(target=self._accept, name='accept').start()

?

??? def stop(self):

??????? for f in self.clients.values():

??????????? f.close()

??????? self.sock.close()

??????? self.event.wait(3)

??????? self.event.set()

?

??? def _accept(self):

? ??????while not self.event.is_set():

??????????? conn, client = self.sock.accept()

??????????? f = conn.makefile(mode='rw')

??????????? self.clients[client] = f

??????????? threading.Thread(target=self._recv, args=(f, client), name='recv').start()

?

??? def _recv(self, f, client):

??????? while not self.event.is_set():

??????????? try:

??????????????? data = f.readline()

??????????? except Exception as e:

??????????????? logging.info(e)

??????????????? data = 'quit'

??????????? data = data.strip()

??????????? logging.info(data)

?

??????????? if data == 'quit':

??????????????? logging.info('{}: ...quit'.format(client))

??????????????? self.clients.pop(client)

??????????????? f.close()

??????????????? break

?

??????????? msg = 'ack: {}'.format(data)

?? ?????????for f in self.clients.values():

??????????????? f.writelines(msg)

??????????????? f.flush()

?

cs = ChatServer()

cs.start()

?

myutils.show_threads()

?

e = threading.Event()

while not e.wait(5):

??? cmd = input('>>> ').strip()

??? if cmd == 'quit':

?? ?????cs.stop()

??????? break

?

?

TCP客戶端編程步驟:

創建socket對象;

連接到遠端服務器的ipportconnect()方法;

傳輸數據,使用send()recv()方法;

關閉連接、釋放資源;

?

TCPUDP的客戶端是隨機的port,而服務器端是綁定死的(提供服務的場所要固定,如銀行);

?

?

例:

sock = socket.socket()?? #step 1

?

ip = '127.0.0.1'

port = 9999

addr = (ip, port)

sock.connect(addr)?? #step 2

?

sock.send(b'hello\n')?? #step3

data = sock.recv(1024)

print(data)

?

sock.close()?? #step4,好習慣,fd資源有限

?

例,ChatClient

class ChatClient():

??? def __init__(self, ip='127.0.0.1', port=9999):

??????? self.sock = socket.socket()

??? ????self.addr = (ip, port)

??????? self.event = threading.Event()

?

??? def start(self):

??????? self.sock.connect(self.addr)

??????? threading.Thread(target=self._recv, name='recv').start()

?

??? def stop(self):

??????? self.sock.close()

??????? self.event.wait(3)

??????? self.event.set()

?

??? def _recv(self):

??????? while not self.event.is_set():

??????????? try:

??????????????? data = self.sock.recv(1024)

??????????? except Exception as e:

??????????????? logging.info(e)

?????????????? ?break

??????????? logging.info(data.decode())

?

??? def send(self):

??????? self.sock.send(data.encode())

?

def main():

??? cc = ChatClient()

??? cc.start()

?

??? myutils.show_threads()

?

??? while True:

??????? cmd = input('>>> ').strip()

??????? if cmd == 'quit':

??????????? cc.send(cmd)

??????????? cc.stop()

??????????? break

??????? cc.send(cmd)

?

if __name__ == '__main__':

??? main()

?


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

神木县| 黑山县| 宁明县| 南溪县| 克东县| 石家庄市| 大港区| 潼南县| 驻马店市| 台江县| 满城县| 黔东| 宝鸡市| 望都县| 阿图什市| 涞水县| 陆川县| 民权县| 朝阳区| 乌兰察布市| 漳浦县| 黄陵县| 元氏县| 郓城县| 西城区| 莒南县| 张掖市| 鄯善县| 咸宁市| 苏尼特左旗| 西城区| 英吉沙县| 区。| 会泽县| 新蔡县| 德兴市| 定襄县| 克拉玛依市| 贵溪市| 巴南区| 龙胜|