成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

10.python網(wǎng)絡(luò)編程(startinpart1)-創(chuàng)新互聯(lián)

一.什么是socket?

創(chuàng)新互聯(lián)公司是一家從事企業(yè)網(wǎng)站建設(shè)、做網(wǎng)站、成都做網(wǎng)站、行業(yè)門戶網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)制作的專業(yè)網(wǎng)站設(shè)計(jì)公司,擁有經(jīng)驗(yàn)豐富的網(wǎng)站建設(shè)工程師和網(wǎng)頁設(shè)計(jì)人員,具備各種規(guī)模與類型網(wǎng)站建設(shè)的實(shí)力,在網(wǎng)站建設(shè)領(lǐng)域樹立了自己獨(dú)特的設(shè)計(jì)風(fēng)格。自公司成立以來曾獨(dú)立設(shè)計(jì)制作的站點(diǎn)上1000+。

socket就是為了實(shí)現(xiàn)C/S架構(gòu)而生的,socket位于應(yīng)用層和傳輸層之間,是傳輸層和應(yīng)用層之間的一組接口,它把復(fù)雜的TCP/IP協(xié)議族隱藏在Socket接口后面,對(duì)用戶來說,一組簡(jiǎn)單的接口就是全部,讓Socket去組織數(shù)據(jù),以符合指定的協(xié)議,所以,我們無需深入理解tcp/udp協(xié)議,socket已經(jīng)為我們封裝好了,我們只需要遵循socket的規(guī)定去編程,寫出的程序自然就是遵循tcp/udp標(biāo)準(zhǔn)的。

也有人將socket說成ip+port,ip是用來標(biāo)識(shí)互聯(lián)網(wǎng)中的一臺(tái)主機(jī)的位置,而port是用來標(biāo)識(shí)這臺(tái)機(jī)器上的一個(gè)應(yīng)用程序,ip地址是配置到網(wǎng)卡上的,而port是應(yīng)用程序開啟的,ip與port的綁定就標(biāo)識(shí)了互聯(lián)網(wǎng)中獨(dú)一無二的一個(gè)應(yīng)用程序。

補(bǔ)充:有人會(huì)把socket和程序的pid弄混,程序的pid是同一臺(tái)機(jī)器上不同進(jìn)程或者線程的標(biāo)識(shí)。

二.socket種類。

  1. 基于文件型套接字。

    AF_UNIX:基于文件型的套接字,就是通過底層的文件系統(tǒng)來取數(shù)據(jù),兩個(gè)套接字進(jìn)程運(yùn)行在同一臺(tái)機(jī)器,可以通過訪問同一個(gè)文件系統(tǒng)來實(shí)現(xiàn)兩個(gè)程序之間的通信。

  2. 基于網(wǎng)絡(luò)型套接字。

三.socket工作流程。

10.python網(wǎng)絡(luò)編程(startin part 1)

tcp服務(wù)端建立連接流程:

socket()實(shí)例化出一個(gè)套接字對(duì)象→bind()綁定ip地址和端口→listen()開始監(jiān)聽之前綁定的ip地址和端口→accept()開始被動(dòng)接收tcp客戶端發(fā)來的連接,會(huì)一直等連接的到來(如果沒有連接,就會(huì)一直等,直到有客戶端連過來。

tcp客戶端建立連接流程:

socket()客戶端也初始化一個(gè)套接字對(duì)象→connect()主動(dòng)去連接服務(wù)端(主動(dòng)初始化與tcp服務(wù)器的連接)如果連接成功,客戶端和服務(wù)器之間就可以互相收發(fā)數(shù)據(jù)了。(其實(shí)connect就相當(dāng)于去回應(yīng)服務(wù)端的accept,服務(wù)端的accept一直在等待客戶端去connect)

客戶端發(fā)送數(shù)據(jù)請(qǐng)求,服務(wù)器端接收請(qǐng)求并處理請(qǐng)求,然后把回應(yīng)數(shù)據(jù)發(fā)送給客戶端,客戶端讀取數(shù)據(jù),最后關(guān)閉連接,一次交互結(jié)束。

四.socket模塊的用法。

import socket

socket.socket(socket_family,socket_type,protocal=0)

socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默認(rèn)值為 0。

獲取tcp/ip套接字

tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

獲取udp/ip套接字

udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

由于 socket 模塊中有太多的屬性。我們?cè)谶@里破例使用了'from module import *'語句。使用 'from socket import *',我們就把 socket 模塊里的所有屬性都帶到我們的命名空間里了,這樣能 大幅減短我們的代碼。

例如tcpSock = socket(AF_INET, SOCK_STREAM)

服務(wù)端常用專屬套接字方法:

s.bind():綁定(主機(jī),端口號(hào))到套接字。

s.listen():開始進(jìn)行tcp監(jiān)聽。#listen方法中可以指定一個(gè)backlog參數(shù),這個(gè)參數(shù)用于設(shè)置tcp連接池的大?。P(guān)于tcp連接池和三次握手的知識(shí)后面會(huì)做補(bǔ)充。)

s.accept():被動(dòng)接受TCP客戶的連接,(阻塞式)等待連接的到來。

客戶端常用專屬套接字方法:

s.connect():主動(dòng)初始化TCP服務(wù)器連接

s.connect_ex() : connect()函數(shù)的擴(kuò)展版本,出錯(cuò)時(shí)返回出錯(cuò)碼,而不是拋出異常。

客戶端和服務(wù)端共同具有的常用套接字方法:

s.recv():接收tcp數(shù)據(jù)。#需要指定每次收多少字節(jié)。

s.send():  發(fā)送tcp數(shù)據(jù),#發(fā)送TCP數(shù)據(jù)(send在待發(fā)送數(shù)據(jù)量大于對(duì)端緩存區(qū)剩余空間時(shí),數(shù)據(jù)丟失,不會(huì)發(fā)完)

s.sendall(): 發(fā)送tcp數(shù)據(jù),發(fā)送完整的TCP數(shù)據(jù)(本質(zhì)就是循環(huán)調(diào)用send,sendall在待發(fā)送數(shù)據(jù)量大于對(duì)端緩存區(qū)剩余空間時(shí),數(shù)據(jù)不丟失,循環(huán)調(diào)用send直到發(fā)完)(個(gè)人分析,本質(zhì)上是調(diào)用了循環(huán))

s.recvfrom():接收UDP數(shù)據(jù)

s.sendto() : 發(fā)送UDP數(shù)據(jù)

s.getpeername() : 連接到當(dāng)前套接字的遠(yuǎn)端的地址

s.getsockname()  :  當(dāng)前套接字的地址

s.getsockopt() :返回指定套接字的參數(shù)

s.setsockopt() : 設(shè)置指定套接字的參數(shù)

s.close() :關(guān)閉套接字

五.socket用法示例。

服務(wù)端:

#!/usr/bin/python2.7

# -*- coding:utf-8 -*-

import socket

address_and_port = ('127.0.0.1',8888)

s1 = socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)

s1.bind(address_and_port)

s1.listen(3)

conn,addr = s1.accept() #執(zhí)行了socket的accept方法后,開始阻塞,等待客戶端的連接.

#執(zhí)行了accept方法后,會(huì)返回一個(gè)元祖,這個(gè)元祖里面包含了一個(gè)客戶端的連接對(duì)象,還有客戶端的ip地址和端口.

while True:

  data = conn.recv(1024) #用于接收tcp數(shù)據(jù),后面的1024表示,recv一次最多可以接收1024字節(jié).(執(zhí)行到recv,如果對(duì)端沒有發(fā)來數(shù)據(jù),或者內(nèi)容為空,程序會(huì)阻塞住,不繼續(xù)向下執(zhí)行。)

  print data

  conn.send(data.upper())

conn.close() #關(guān)閉與客戶端的連接

s1.close()  #關(guān)閉服務(wù)端套接字連接

客戶端:

#!/usr/bin/python2.7

# -*- coding:utf-8 -*-

import socket

s1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s1.connect(('127.0.0.1',8888))

while True:

  msg = raw_input(">>>").strip()

  s1.send(msg.encode(('utf-8')))

  print "客戶端已發(fā)送數(shù)據(jù)!"

  data = s1.recv(1024)

  print data

#上面兩個(gè)代碼,可以簡(jiǎn)單理解下socket的工作流程。

六.解決sockt 通信客戶端斷開服務(wù)端崩潰等問題的解決方法(連接循環(huán),通信循環(huán),以及異常捕捉)

服務(wù)端:

#!/usr/bin/python2.7

# -*- coding:utf-8 -*-

import socket

address_and_port = ('127.0.0.1',8888)

s1 = socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)

s1.bind(address_and_port)

s1.listen(3)

while True:  #此處問連接循環(huán),會(huì)循環(huán)等連接。

  conn,addr = s1.accept() #執(zhí)行了socket的accept方法后,開始阻塞,等待客戶端的連接.

    #執(zhí)行了accept方法后,會(huì)返回一個(gè)元祖,這個(gè)元祖里面包含了一個(gè)客戶端的連接對(duì)象,還有客戶端的ip地址和端口.

  while True:  #數(shù)據(jù)傳輸循環(huán)

    try:   #防止客戶端斷開導(dǎo)致的服務(wù)斷拋異常。

      data = conn.recv(1024) #用于接收tcp數(shù)據(jù),后面的1024表示,recv一次最多可以接收1024字節(jié).

      if not data:

        break

      print data

      conn.send(data.upper())

    except Exception:

      break

conn.close() #關(guān)閉與客戶端的連接

s1.close()  #關(guān)閉服務(wù)端套接字連接

客戶端:

#!/usr/bin/python2.7

# -*- coding:utf-8 -*-

import socket

s1 = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s1.connect(('127.0.0.1',8888))

while True:

  msg = raw_input(">>>").strip()

  if not msg:  #防止客戶端發(fā)送空數(shù)據(jù)

    continue

  s1.send(msg.encode(('utf-8')))

  print "客戶端已發(fā)送數(shù)據(jù)!"

  data = s1.recv(1024)

  print data

s1.close()

#以上是防止服務(wù)端崩潰的一些解決方法。

七.關(guān)于udp套接字。

服務(wù)端大概操作流程:

ss = socket()  #創(chuàng)建一個(gè)服務(wù)器的套接字

ss.bind()    #綁定服務(wù)器套接字

inf_loop:    #服務(wù)器無限循環(huán)

cs = ss.recvfrom()/ss.sendto() # 對(duì)話(接收與發(fā)送)

ss.close()             # 關(guān)閉服務(wù)器套接字

客戶端大概的操作流程:

cs = socket()  # 創(chuàng)建客戶套接字

comm_loop:    # 通訊循環(huán)

  cs.sendto()/cs.recvfrom()  # 對(duì)話(發(fā)送/接收)

cs.close()            # 關(guān)閉客戶套接字

下面是udp套接字的一個(gè)簡(jiǎn)單的示例:

 示例1:

服務(wù)端:

import socket

udp_server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

udp_server.bind(('127.0.0.1',8888))

while True:

  msg,addr = udp_server.recvfrom(1024)

  print msg ,addr

  udp_server.sendto(msg.upper(),addr)

客戶端:

import socket

udp_client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

while True:

  msg = raw_input(">>:").strip()

  if not msg:

    continue

  udp_client.sendto(msg.encode('utf-8'),("127.0.0.1",8888))

  back_msg,addr = udp_client.recvfrom(1024)

  print back_msg.decode('utf-8') ,addr

八.關(guān)于tcp套接字和udp套接字你需要知道的。

  1. 首先有幾點(diǎn)必須明確!

    1.1  所有的收發(fā)消息,都是在操作自己的tcp/udp緩沖區(qū),發(fā)消息是將數(shù)據(jù)發(fā)送到自己的緩沖區(qū)中,收消息同樣也是從緩沖區(qū)中收取。

    1.2 tcp 使用send發(fā)消息,使用recv收消息

    1.3udp 使用sendto發(fā)消息,使用recvfrom收消息

  2. tcp與udp

    2.1 tcp是基于流的,udp是基于報(bào)的

2.2 使用send發(fā)送數(shù)據(jù)流的時(shí)候,若數(shù)據(jù)流為空,那么tcp buffer(緩沖區(qū))也為空,操作系統(tǒng)不會(huì)控制tcp發(fā)包。

sendinto(bytes_data,ip_port):發(fā)送數(shù)據(jù)報(bào),bytes_data為空,還有ip_port,所有即便是發(fā)送空的bytes_data,數(shù)據(jù)報(bào)其實(shí)也不是空的,自己這端的緩沖區(qū)收到內(nèi)容,操作系統(tǒng)就會(huì)控制udp協(xié)議發(fā)包。

3.關(guān)于tcp的補(bǔ)充

tcp基于鏈接通信:

    基于鏈接,則需要listen(backlog),指定半連接池的大小

    基于鏈接,必須先運(yùn)行的服務(wù)端,然后客戶端發(fā)起鏈接請(qǐng)求

    對(duì)于mac系統(tǒng):如果一端斷開了鏈接,那另外一端的鏈接也跟著完蛋recv將不會(huì)阻塞,收到的是空(解        決方法是:服務(wù)端在收消息后加上if判斷,空消息就break掉通信循環(huán))

    對(duì)于windows/linux系統(tǒng):如果一端斷開了鏈接,那另外一端的鏈接也跟著完蛋recv將不會(huì)阻塞,收到        的是空(解決方法是:服務(wù)端通信循環(huán)內(nèi)加異常處理,捕捉到異常后就break掉通訊循環(huán))

udp通信。

無鏈接,因而無需listen(backlog),更加沒有什么連接池之說了

無鏈接,udp的sendinto不用管是否有一個(gè)正在運(yùn)行的服務(wù)端,可以己端一個(gè)勁的發(fā)消息,只不過數(shù)據(jù)丟失

recvfrom收的數(shù)據(jù)小于sendinto發(fā)送的數(shù)據(jù)時(shí),在mac和linux系統(tǒng)上數(shù)據(jù)直接丟失,在windows系統(tǒng)上發(fā)送的比接收的大直接報(bào)錯(cuò)

只有sendinto發(fā)送數(shù)據(jù)沒有recvfrom收數(shù)據(jù),數(shù)據(jù)丟失。

注意:

1.你單獨(dú)運(yùn)行上面的udp的客戶端,你發(fā)現(xiàn)并不會(huì)報(bào)錯(cuò),相反tcp卻會(huì)報(bào)錯(cuò),因?yàn)閡dp協(xié)議只負(fù)責(zé)把包發(fā)出去,對(duì)方收不收,我根本不管,而tcp是基于鏈接的,必須有一個(gè)服務(wù)端先運(yùn)行著,客戶端去跟服務(wù)端建立鏈接然后依托于鏈接才能傳遞消息,任何一方試圖把鏈接摧毀都會(huì)導(dǎo)致對(duì)方程序的崩潰。

2.上面的udp程序,你注釋任何一條客戶端的sendinto,服務(wù)端都會(huì)卡住,為什么?因?yàn)榉?wù)端有幾個(gè)recvfrom就要對(duì)應(yīng)幾個(gè)sendinto,哪怕是sendinto(b'')那也要有。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

文章題目:10.python網(wǎng)絡(luò)編程(startinpart1)-創(chuàng)新互聯(lián)
網(wǎng)頁路徑:http://jinyejixie.com/article22/djedcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)標(biāo)簽優(yōu)化、自適應(yīng)網(wǎng)站、App設(shè)計(jì)、小程序開發(fā)、Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)
西和县| 辽宁省| 婺源县| 江川县| 江安县| 洪湖市| 库尔勒市| 前郭尔| 都江堰市| 五大连池市| 巩留县| 汽车| 内黄县| 应城市| 泸水县| 兴文县| 华池县| 巴马| 靖西县| 衡南县| 淳安县| 江陵县| 永春县| 威宁| 东源县| 建湖县| 手游| 沙坪坝区| 临安市| 宁南县| 新巴尔虎右旗| 砀山县| 郯城县| 江安县| 阿合奇县| 涪陵区| 中江县| 汽车| 响水县| 隆昌县| 弥勒县|