套接字:鏈接應用層和運輸層,應用層的網絡應用程序使用IP地址+端口號來標識本身,而後經過套接字調用運輸層爲其服務,網絡應用程序只能指定本身要使用的網絡類型,並設置一些普通參數,例如緩存大小等,除此以外的全部都要運輸層本身完成。python
爲了學習套接字如何操做運輸層的UDP和TCP協議,此處提出一個需求:客戶端接收用戶輸入的信息,併發送到服務器上,並接收由服務器把全部字母大寫以後的數據,再顯示出來。
整個過程須要如下步驟:
1.客戶端提示用戶信息輸入並將數據發送給服務器
2.服務器接收信息,把字幕轉換爲大寫
3.服務器將修改好的數據再次發送給客戶端
4.客戶端接收到服務器發送來的數據,並將其顯示出來編程
必需要先運行服務器端程序,保證服務器是處於運行狀態的,客戶端才能跟服務器進行通訊。api
UDP不須要先通過三次握手確保創建了鏈接,因此要在每一個要傳輸的報文上攜帶目的地址緩存
客戶端代碼:服務器
# -*- coding:utf-8 -*- from socket import * #設置服務器主機名或者IP地址 serverName = '127.0.0.1' #設置主機的接收進程,即端口號 serverPort = 12000 #建立客戶端套接字,AF_INET指示底層用IPv4, SOCK_DGRAM指定是UDP套接字不是TCP套接字 clientSocket = socket(AF_INET,SOCK_DGRAM) #客戶端提示用戶輸入信息 message = raw_input("Input lowercase sentence:") #發送報文到目的地 #sendto()方法爲報文附上目的地址,而且向進程的套接字clientSocket發送結果分組 clientSocket.sendto(message, (serverName, serverPort)) #當有數據到達客戶端的套接字時,使用recvfrom()方法接收,指定緩存長度爲2048 modifiedMessage, serverAddress = clientSocket.recvfrom(2048) #打印剛剛接收到的信息 print modifiedMessage, serverAddress #關閉套接字 clientSocket.close()
服務器端代碼:網絡
# -*- coding:utf-8 -*- from socket import * #定義一個端口號 serverPort = 12000 #實例化一個服務器端的套接字,AF_INET指定使用IPv4,SOCK_DGRAM指定使用UDP serverSocket = socket(AF_INET, SOCK_DGRAM) #爲服務器端套接字綁定一個端口 serverSocket.bind(('', serverPort)) print "The server is ready to receive" #處於循環監聽狀態 while True: #當有數據到達本地的12000端口的套接字處時,使用recvfrom()接收 message, clientAddress = serverSocket.recvfrom(2048) #對接收到的數據進行處理 modifiedMessage = message.upper() #使用sendto()發送數據到客戶端 serverSocket.sendto(modifiedMessage, clientAddress)
一樣,先運行服務器端的程序併發
TCP須要先通過三次握手在客戶端和服務器之間鏈接鏈接,而後再傳輸數據,因此,在創建鏈接時須要指定目的地址,而在傳輸數據時就不須要再附帶目的地址數據了。
須要注意的是:服務器監聽全部客戶端發來的鏈接請求,若是發現有請求,就爲其創建一個新的鏈接來傳輸數據。socket
客戶端程序:tcp
# -*- coding:utf-8 -*- from socket import * #服務器端的IP地址或名稱和端口號 serverName = '127.0.0.1' serverPort = 12000 #實例化套接字,SOCK_STREAM指定使用的是TCP協議 clientSocket = socket(AF_INET, SOCK_STREAM) #客戶端和服務器端創建鏈接 clientSocket.connect((serverName, serverPort)) #提示用戶輸入信息 sentence = raw_input("Input lowercase sentence:") #客戶端發送數據到服務器,此處不一樣於UDP #此處沒有爲數據指定地址,是由於已經和服務器創建和鏈接,能夠直接通訊了 clientSocket.send(sentence) #接收返回的數據 modifiedSentence = clientSocket.recv(1024) #打印顯示服務器端發回來的數據 print 'From Server:', modifiedSentence #關閉客戶端套接字鏈接 clientSocket.close()
服務器端程序:學習
# -*- coding:utf-8 -*- from socket import * #定義端口號變量 serverPort = 12000 #實例化服務端套接字,SOCK_STREAM指定使用TCP協議 serverSocket = socket(AF_INET, SOCK_STREAM) #爲套接字綁定端口號 serverSocket.bind(('', serverPort)) #監聽來自客戶端的請求,其中參數定義了最大鏈接數 serverSocket.listen(1) print 'The server is ready to receive' #循環監聽 while 1: #服務器監聽到來自客戶端的請求,使用accept()爲其建立一個新的專用的鏈接。 #此處不一樣與UDP,TCP在通過公用的三次握手以後,爲其創建一個新鏈接供其傳輸數據 connectionSocket, addr = serverSocket.accept() #接收客戶端發送來的數據 sentence = connectionSocket.recv(1024) #操做接收到的數據 capitalizedSentence = sentence.upper() #發送數據到客戶端 connectionSocket.send(capitalizedSentence) #斷開鏈接 connectionSocket.close()