假期(網路程式設計)

2021-09-25 11:11:54 字數 4330 閱讀 7093

"""

一、客戶端/服務端架構:

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個人,對於每個住校學生,肯定需要床,那麼就將自...