日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本篇包括網絡編程概述、UDP簡介、TFTP簡介、TCP編程等。

目錄

一、tcp/ip協議簡介

二、端口

三、IP地址

四、mac地址

五、socket簡介

六、UDP網絡通信過程

七、模擬QQ聊天-多線程實現

八、wireshark抓包工具的使用

九、tftp下載器的使用(tftpd64或tftpd32)

十、UDP廣播

十一、TCP服務器、客戶端簡介及實現

11.1 TCP簡介

11.2 TCP和UDP通信模型

11.3 Python實現tcp服務器和客戶端

一、tcp/ip協議簡介

tcp/ip不是兩個協議,而是一個協議組,實際為4層,邏輯上可以為7層,如下圖所示:

網絡編程——協議基礎

 

二、端口

為什么使用端口?只有ip地址時只知道發往哪個電腦而不知道發往哪個程序,端口用來辨識要發往的具體程序。

為什么不用PID辨識進程?因為進程是動態的,遠端電腦可能不知道本地的pid號。

知名端口:大家都知道的約定好的端口,如80端口為HTTP服務,21端口為FTP服務,范圍為0~1023。

動態端口:用戶自己定義的端口,范圍為1024~65535.

查看端口命令:

注意:在同一個OS中,端口不允許相同,如果某個端口已經被使用了,那么在這個進程釋放這個端口之前,其他進程不能使用這個端口。因為端口用來區分一個進程。

網絡編程——協議基礎

 

三、IP地址

用來邏輯上表示網絡上的唯一一臺電腦。

注意:一個電腦可以有多個網卡,即多個IP地址!

IP地址分類

其中網絡號固定不變,表示位于同一網絡中的電腦,主機號為當前網絡中的電腦號。

主機號為0時表示網段號,主機號為255時為網關。

D類用于多播(不是廣播),例如視頻會議,只有一些人可以看到。

E類實驗和開發用。

網絡編程——協議基礎

 

私有ip

用于局域網中,訪問公網時不能使用,需要轉換為公有ip訪問外網。范圍如下:

網絡編程——協議基礎

 

注意

IP地址127.0.0.1~127.255.255.255用于回路測試,即測試當前電腦tcp/ip協議能不能用,例如ping 127.0.0.1,即使拔掉網線也能ping得通。

linux服務器開發學習視頻資料,包括Linux,Nginx,ZeroMQ,MySQL,redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK等等。

需要知識技術學習視頻文檔資料的朋友可以后臺私信【架構】獲取

網絡編程——協議基礎

 


網絡編程——協議基礎

 

四、MAC地址

網卡的序列號,形如XX:XX:XX:XX:XX:XX,六組十六進制數,前三組表示廠商序列號,后三組表示網卡序列號。

五、socket簡介

socket:通過網絡使進程間通信。

注意:一個進程可以有多個socket!

python測試程序如下:

網絡編程——協議基礎

 

端口綁定(只能綁定自己的端口!)

上面程序每次運行時操作系統為它分配的端口不一樣,這導致了遠端電腦不知道每次運行的端口,不能發送信息到本地。

python程序如下:

注意:bindAddr中第一個參數為空,因為該參數表示本地IP地址,但本地可能有多個IP,空表示任意ip都進行綁定。

網絡編程——協議基礎

 

六、UDP網絡通信過程

應用層填寫需要發送的數據;傳輸增加上端口號等;網絡層加上目的ip等;鏈路層加上目的mac等;如下圖:

網絡編程——協議基礎

 

七、模擬QQ聊天-多線程實現

全雙工實現QQ聊天,代碼如下:

from threading import Thread

from socket import *

 

#1. 收數據,然后打印

def recvData():

while True:

recvInfo = udpSocket.recvfrom(1024)

print(">>%s:%s"%(str(recvInfo[1]), recvInfo[0]))

 

#2. 檢測鍵盤,發數據

def sendData():

while True:

sendInfo = input("<<")

udpSocket.sendto(sendInfo.encode("gb2312"), (destIp, destPort))

 

udpSocket = None

destIp = ""

destPort = 0

 

def main():

 

global udpSocket

global destIp

global destPort

 

destIp = input("對方的ip:")

destPort = int(input("對方的ip:"))

 

udpSocket = socket(AF_INET, SOCK_DGRAM)

udpSocket.bind(("", 4567))

 

tr = Thread(target=recvData)

ts = Thread(target=sendData)

 

tr.start() #啟動接收數據線程

ts.start() #啟動發送數據線程

 

tr.join() #等待兩個線程結束

ts.join()

 

if __name__ == "__main__":

main()

八、wireshark抓包工具的使用

wireshark工具可以抓取當前電腦中所有網絡數據,具體如圖所示:

網絡編程——協議基礎

 

九、tftp下載器的使用(tftpd64或tftpd32)

tftp是tcp/ip協議族中用來將客戶端和服務器之間進行簡單文件傳輸的協議。

特點如下:

基于UDP實現,可能會丟包,實現過程為收到-回復,下載過程如下:

網絡編程——協議基礎

 

TFTP數據表格式如下:

讀寫請求格式:操作碼為1或2,分別表示讀或寫;文件名為文件名稱;0為固定寫法;模式有幾種,最常用的為octet;最后跟一個0。

數據表格式:操作碼固定為3;文件名為文件名稱;塊編號為文件分割的塊編號;數據為詳細數據。

確認格式:操作碼固定為4;塊編號為確認收到的文件分塊編號。

錯誤表格式:操作碼固定為5;差錯碼為固定好的錯誤編號;后面接具體差錯信息;最后跟一個0;

注意:確認包發往的是服務器發送本地進程時分配的隨機端口!

怎樣確定數據已經發送完畢了?

規定, 當客戶端接收到的數據?于516(2字節操作碼+2個字節的序號+512字節數據) 時, 就意味著服務器發送完畢了。

怎樣保證包中每個碼的字節數?

python中組包代碼如下:

網絡編程——協議基礎

 

!:表示網絡中的數據,網絡中的數據用大端表示。

H:占用2個字節,對應后面的1。

8s:占用8個字節,對應后面的"test.jpg"。

b:占用1個字節,對應后面的0。

5s:占用5個字節,對應后面的"octet"。

b:占用1個字節,對應后面的0。

表格式如圖所示:

網絡編程——協議基礎

 

使用python從tftp服務器中下載文件

1)首先啟動tftpd64應用程序,設置好下載的目錄和ip地址。

2)python代碼如下:

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

 

import struct

from socket import *

import time

import os

 

def main():

 

#0. 獲取要下載的文件名字:

downloadFileName = raw_input("請輸入要下載的文件名:")

 

#1.創建socket

udpSocket = socket(AF_INET, SOCK_DGRAM)

 

requestFileData = struct.pack("!H%dsb5sb"%len(downloadFileName), 1, downloadFileName, 0, "octet", 0)

 

#2. 發送下載文件的請求

udpSocket.sendto(requestFileData, ("192.168.119.215", 69))

 

flag = True #表示能夠下載數據,即不擅長,如果是false那么就刪除

num = 0

f = open(downloadFileName, "w")

 

while True:

#3. 接收服務發送回來的應答數據

responseData = udpSocket.recvfrom(1024)

 

# print(responseData)

recvData, serverInfo = responseData

 

opNum = struct.unpack("!H", recvData[:2])

 

packetNum = struct.unpack("!H", recvData[2:4])

 

print(packetNum[0])

 

# print("opNum=%d"%opNum)

# print(opNum)

 

# if 如果服務器發送過來的是文件的內容的話:

if opNum[0] == 3: #因為opNum此時是一個元組(3,),所以需要使用下標來提取某個數據

 

#計算出這次應該接收到的文件的序號值,應該是上一次接收到的值的基礎上+1

num = num + 1

 

# 如果一個下載的文件特別大,即接收到的數據包編號超過了2個字節的大小

# 那么會從0繼續開始,所以這里需要判斷,如果超過了65535 那么就改為0

if num==65536:

num = 0

 

# 判斷這次接收到的數據的包編號是否是 上一次的包編號的下一個

# 如果是才會寫入到文件中,否則不能寫入(因為會重復)

if num == packetNum[0]:

# 把收到的數據寫入到文件中

f.write(recvData[4:])

num = packetNum[0]

 

#整理ACK的數據包

ackData = struct.pack("!HH", 4, packetNum[0])

udpSocket.sendto(ackData, serverInfo)

 

elif opNum[0] == 5:

print("sorry,沒有這個文件....")

flag = False

 

# time.sleep(0.1)

 

if len(recvData)<516:

break

 

if flag == True:

f.close()

else:

os.unlink(downloadFileName)#如果沒有要下載的文件,那么就需要把剛剛創建的文件進行刪除

 

if __name__ == '__main__':

main()

十、UDP廣播

UDP廣播不是對每個用戶輪流發送數據,而是發送到交換機,交換機負責同時發送給每個用戶。

廣播可用于動態獲取ip地址。

單播----點對點;多播----一對多;廣播----一無所有。

注意:廣播只用于UDP中,TCP不能廣播!

python簡單實現:

網絡編程——協議基礎

 

十一、TCP服務器、客戶端簡介及實現

11.1 TCP簡介

tcp:傳輸控制協議

特點:1、穩定;2、相對udp而言要慢一些;3、web服務器都是使用的tcp;

udp:用戶數據包協議

特點:1、不穩定;2、相對tcp而言要快一些;

11.2 TCP和UDP通信模型

udp通信模型:相當于寫信;

網絡編程——協議基礎

 

tcp通信模型:相當于打電話;

socket創建出來的套接字,默認為主動套接字,即發送數據給別人。listen()將主動套接字變為被動套接字。

TCP服務器端:

1、買個手機 socket(xxx);

2、插入手機卡 bind(xxx);

3、設置手機為響鈴模式 listen();

4、等待別人的電話,準備好接聽 accept();

TCP客戶端:

1、買個手機 socket(xxx);

2、撥打電話 connect(xxx);

網絡編程——協議基礎

 

11.3 python實現tcp服務器和客戶端

tcp服務器端實現(簡單原理實現,非實際的多進程)如下:

注意:

accept用來接收客戶端請求,并重新創建一個socket為新的客戶服務,然后等待下一個客戶端的請求。

clientSocket用來專門為新的客戶端服務。

代碼解釋:

第一個while循環用來監聽是否有新客戶接入,并為它分配服務資源。

第二個while循環為新的客戶端服務。注意:當客戶端下線時,newSocket.recv(1024)這句可以解阻塞,且返回值為0,從而可以跳出循環。

該程序為單任務,實際服務器為多進程實現,只需將第二個while定義為一個函數,在第一個while中啟動一個進程執行該函數即可。

#coding=utf-8

from socket import *

# 創建socket

tcpSerSocket = socket(AF_INET, SOCK_STREAM)

# 綁定本地信息

address = ('', 7788)

tcpSerSocket.bind(address)

 

# 使?socket創建的套接字默認的屬性是主動的, 使?listen將其變為被動的, 這樣就可以接收。

# 5表示服務器同一時刻最多允許5個客戶端發數據

tcpSerSocket.listen(5)

 

while True:

# 如果有新的客戶端來連接服務器, 那么就產??個新的套接字專?為這個客戶端服務器

# newSocket?來為這個客戶端服務

# tcpSerSocket就可以省下來專?等待其他新客戶端的鏈接

newSocket, clientAddr = tcpSerSocket.accept()

 

# 該循環為新的客戶端服務。注意:當客戶端下線時,newSocket.recv(1024)這句可以解阻塞,且返回

# 值為0,從而可以跳出循環

while True:

# 接收對?發送過來的數據, 最?接收1024個字節

recvData = newSocket.recv(1024)

 

# 如果接收的數據的?度為0, 則意味著客戶端關閉了鏈接

if len(recvData)>0:

print 'recv:',recvData

else:

break

 

# 發送?些數據到客戶端

sendData = raw_input("send:")

newSocket.send(sendData)

 

# 關閉為這個客戶端服務的套接字, 只要關閉了, 就意味著為不能再為這個客戶端服務了

newSocket.close()

 

# 關閉監聽套接字, 只要這個套接字關閉了, 就意味著整個程序不能再接收任何新的客戶端的連接

tcpSerSocket.close()

tcp客戶器端實現如下:

from socket import *

 

#創建TCP套接字

clientSocket = socket(AF_INET, SOCK_STREAM)

#鏈接服務器

clientSocket.connect(("192.168.119.153", 8989))

 

#注意:

# 1. tcp客戶端已經連接好了服務器,所以在以后的數據發送中,不需要填寫對方的iph和port----->打電話

# 2. udp在發送數據的時候,因為沒有之前的鏈接,所以需要 在每次的發送中 都要填寫接收方的ip和port----->寫信 

 

#發送數據

clientSocket.send("haha".encode("gb2312"))

#接收數據

recvData = clientSocket.recv(1024)

#打印接收到的數據

print("recvData:%s"%recvData)

#關閉客戶端socket

clientSocket.close()

分享到:
標簽:網絡編程
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定