"""一、客戶端/服務端架構:
1、硬體c/s架構(印表機)
2、軟體c/s架構
網際網路中處處都是cs架構,服務端與客戶端
cs架構與socket的關係
- 我們學習socket就是為了完成c/s架構的開發
二、osi七層模型:
乙個完整的計算機系統是由硬體、作業系統、應用軟體三者組成,一台計算機只能自己玩自己,要想跟別人玩就需要上網了
網際網路的核心就是由一堆協議組成,協議就是標準,比如全世界人通訊的標準是英語;
如果把計算機比做人,那麼網際網路協議就是計算機界的英語了,如果所有的計算機都學會了這門英語,那麼就可以互相通訊了
為何學習socket一定要先學習網際網路協議:
- 1、首先我們的目標是基於socket程式設計,來開發一款自己的cs架構軟體
- 2、其次cs架構軟體(軟體屬於應用層)是基於網路進行通訊的
- 3、網路的核心即一堆協議,協議即標準,你想開發一款基於網路通訊的軟體,就必須遵循這些標準
三、socket層
socket層位於運輸層和應用層之間,即socket抽象層
四、socket是什麼?
socket是應用層與tcp/ip協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,socket其實就是乙個門面模式,它吧複雜的
tcp/ip協議族隱藏在了socket介面的後面,對使用者來說,一組簡單的介面就是全部,讓socket去組織資料,以符合指定的協議
所以我們無需深入理解tcp/udp協議,socket已經幫我們封裝好了,我們只需要遵循socket的規定去程式設計,寫出的程式自然符合標準
- 也有人將socket說成是ip+port,ip是用來標識網際網路中的一台主機的位置,而port是用來標識這台主機上的乙個應用程式,ip位址
配置到網絡卡上的,而port是應用程式開啟的,ip與port的繫結就標識了網際網路中獨一無二的應用程式
程式的pid是同一臺機器上不同程序或者執行緒的標識
五、套接字的分類:
- 基於檔案型別的套接字家族
套接字家族的名字:af_unix
unix一切皆檔案,基於檔案的套接字呼叫的就是底層檔案系統來取資料,兩個套接字程序執行在同一機器,可以通過訪問同乙個
間接完成通訊。
- 基於網路型別的套接字家族
套接字家族的名字:af_inet
···所有的位址家族中,af_inet是使用最廣泛的乙個,python支援很多種位址家族,但是由於我們只關心網路程式設計,所以我們
大部分時間都只是使用af_inet
六、套接字的工作流程:
就可以進行不正當的交易了。交易完成後,結束通話**結束此次交談;
先從服務端說起,服務端先初始化socket,然後與埠繫結(bind),對埠進行監聽(listen),呼叫accept阻塞,等待客戶端鏈結
在這個時候如果有客戶端初始化乙個socket,然後鏈結伺服器(connect),如果鏈結成功,這時客戶端與服務端的鏈結就建立了。
客戶端傳送資料請求,服務端接收請求並處理,然後把回應資料傳送給客戶端,客戶端讀取資料,關閉鏈結,互動結束
- socket函式的用法
import socket
socket.socket(socket_family,socket_type,protocal=0)
socket_family:可以是af_unix或者是af_inet;socket_type可以是sock_stream或sock_dgram,protocol一般預設為0
獲取tcp/ip 套接字
tcpsock = socket.socket(socket.af_inet,socket.sock_stream)
獲取udp/ip 套接字
udpsock = socket.socket(socket.af_inet,socket.sock_dgram)
由於socket模組中有太多的屬性,我們直接在這裡使用 from *** import * 的語句匯入,這樣就可以減少**量
eg:tcpsock = socket(af_inet,sock_stream)
- 服務端套接字函式
s.bind()繫結(主機,埠號)到套接字
s.listen()開始tcp監聽
s.accept()被動接受tcp客戶的連線,(阻塞式)等待連線的到來
- 客戶端套接字函式
c.connect()被動初始化tcp伺服器連線
c.connect_ex() connect()函式的擴充套件版本,出錯時返回錯誤碼,而不是丟擲異常
- 公共用途的套接字函式
s.recv()接受tcp資料
s.send()傳送tcp資料(send在待傳送資料量大於已快取區剩餘的空間時,資料丟失,不會發完)
s.sendall()傳送完整的tcp資料(本質就是迴圈send,···資料不會丟失)
s.recvfrom()接受udp資料
s.sendto()傳送udp資料
s.getsockname()當前套接字的位址
s.getsockopt()返回指定套接字的引數
s.setsockopt()設定指定套接字的引數
s.close()關閉套接字鏈結
- 面向鎖的套接字方法
s.setblocking()設定套接字的阻塞與非阻塞模式
s.settimeout()設定阻塞套接字操作的超時時間
s.gettimeout()得到阻塞套接字操作的超時時間
- 面向檔案的套接字函式
s.fileno()套接字的檔案描述符
s.makefile()建立乙個與該套接字相關的檔案
七、基於tcp的套接字
tcp是基於鏈結的,必須先啟動服務端,然後再啟動客戶端去鏈結服務端
- tcp服務端:
server = socket() #建立伺服器套接字
server.setsockopt(sol_socket,so_reuseaddr,1)
server.bind() #把位址繫結到套接字
server.listen() #監聽鏈結
while true: #伺服器無限迴圈
client,addr = server.accept() #接受客戶端鏈結
while true: #通訊迴圈
client.recv()/client.send() #接收與傳送資料
client.close() #關閉客戶端套接字
server.close() #關閉伺服器套接字
- tcp客戶端:
client = socket() #建立客戶端套接字
client.connect() #嘗試鏈結伺服器
while true:
client.send()/client.recv() #傳送/接收資料
client.close() #關閉客戶端套接字
八、基於udp的套接字
- udp服務端
server = socket() #建立伺服器套接字
server.bind() #繫結套接字位址
while true: #伺服器無線迴圈
client,addr = server.recvfrom()/server.sendto() #接收與傳送資料
server.close() #關閉伺服器套接字
- udp客戶端
client = socket() #建立客戶端套接字
while true: #通訊迴圈
client.sendto()/client.recvfrom() #傳送與接收資料
client.close() #關閉客戶端套接字
九、粘包現象(了解)
如果當我們用socket模擬cmd執行遠端命令時,有些資料太長,超過了1024個位元組,一次接受不完,就會造成粘包
- 什麼是粘包?
只有tcp才有粘包現象,udp永遠不會粘包,因為udp是基於流收發資料的
所謂粘包的問題主要還是因為接收方不知道訊息之間的界限,不知道一次性提取多少資料造成的
- 粘包的解決
- struct模組
- 自定義報頭
- ···
- 什麼時候才會發生粘包?
傳送端需要等緩衝區滿才傳送出去,造成粘包(傳送資料時間間隔很短,資料很小會喝到一起,產生粘包)
接收方不及時接收緩衝區的包,造成多個包接收產生粘包
- 了解
tcp是可靠傳輸,udp是不可靠傳輸
十、socketserver模組
- 終極必殺技
"""
程式設計題 假期
時間限制 c c 2秒,其他語言4秒 空間限制 c c 256m,其他語言512m 由於業績優秀,公司給小q放了 n 0 n 100000 天的假,身為工作狂的小q打算在在假期中工作 鍛鍊或者休息。他有個奇怪的習慣 不會連續兩天工作或鍛鍊。只有當公司營業時,小q才能去工作,只有當健身房營業時,小q才...
假期學習 五 RDD程式設計實驗四
今天完成了實驗四的第二問和第三問 第二題對於兩個輸入檔案 a 和 b,編寫 spark 獨立應用程式,對兩個檔案進行合併,並剔除其 中重複的內容,得到乙個新檔案 c。下面是輸入檔案和輸出檔案的乙個樣例,供參考。輸入檔案 a 的樣例如下 20170101 x 20170102 y 20170103 x...
洛谷2055 假期的宿舍(網路流)
良心的資料範圍,肯定就是o 因為題目中給出了許多關係,最後詢問是否能全部解決,那麼就相當於給了匹配關係,詢問最大匹配數與總數之間的關係,所以網路流的解法就出來了。對於每個非在校學生和要回家的學生,肯定就不需要考慮他們了,將他們與s連容量為1的邊限制最多1個人,對於每個住校學生,肯定需要床,那麼就將自...