和客戶端編程相比定嗓,服務(wù)器編程就要復(fù)雜一些。
服務(wù)器進(jìn)程首先要綁定一個(gè)端口并監(jiān)聽來(lái)自其他客戶端的連接。如果某個(gè)客戶端連接過(guò)來(lái)了厚柳,服務(wù)器就與該客戶端建立Socket連接,隨后的通信就靠這個(gè)Socket連接了沐兵。
所以别垮,服務(wù)器會(huì)打開固定端口(比如80)監(jiān)聽,每來(lái)一個(gè)客戶端連接扎谎,就創(chuàng)建該Socket連接宰闰。由于服務(wù)器會(huì)有大量來(lái)自客戶端的連接,所以簿透,服務(wù)器要能夠區(qū)分一個(gè)Socket連接是和哪個(gè)客戶端綁定的移袍。一個(gè)Socket依賴4項(xiàng):服務(wù)器地址、服務(wù)器端口老充、客戶端地址葡盗、客戶端端口來(lái)唯一確定一個(gè)Socket。
但是服務(wù)器還需要同時(shí)響應(yīng)多個(gè)客戶端的請(qǐng)求啡浊,所以觅够,每個(gè)連接都需要一個(gè)新的進(jìn)程或者新的線程來(lái)處理,否則巷嚣,服務(wù)器一次就只能服務(wù)一個(gè)客戶端了喘先。
我們來(lái)編寫一個(gè)簡(jiǎn)單的服務(wù)器程序,它接收客戶端連接廷粒,把客戶端發(fā)過(guò)來(lái)的字符串加上Hello再發(fā)回去窘拯。
多線程的echo服務(wù)器的缺點(diǎn)是:
對(duì)于每一個(gè)連接都要?jiǎng)?chuàng)建一個(gè)線程红且,這個(gè)開銷還是很大的。但是對(duì)于單線程的服務(wù)器涤姊,它起碼解決了阻塞的問(wèn)題暇番。對(duì)于它的改進(jìn)方法,參考http://www.reibang.com/p/8a360a3f13aa
server端代碼:
#coding:utf-8
import socket
import threading
import time
def tcplink(sock, addr):
print('Accept new connection from %s:%s...' % addr)
sock.send(b'Welcome!')
while True:
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data.decode('utf-8')).encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.' % addr)
#建立一個(gè)socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#監(jiān)聽9999端口
s.bind(('127.0.0.1', 9999))
#緊接著思喊,調(diào)用listen()方法開始監(jiān)聽端口壁酬,傳入的參數(shù)指定等待連接的最大數(shù)量
s.listen(5)
print('Waiting for connection...')
while True:
# 接受一個(gè)新連接: 返回的sock用來(lái)通信,addr是客戶機(jī)的地址
sock, addr = s.accept()
# 創(chuàng)建新線程來(lái)處理TCP連接:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
<br />
client 代碼:
#coding:utf-8
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立連接:
s.connect(('127.0.0.1', 9999))
# 接收歡迎消息:
print(s.recv(1024).decode('utf-8'))
for data in [b'Michael', b'Tracy', b'Sarah']:
# 發(fā)送數(shù)據(jù):
s.send(data)
print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
運(yùn)行結(jié)果:
相關(guān)文章:
一個(gè)基于python的單線程的echo服務(wù)器
http://www.reibang.com/p/8f1941c4a549
基于python的一個(gè)多線程echo服務(wù)器
http://www.reibang.com/p/2ffde49b55c3
一個(gè)基于select模型的echo服務(wù)器
http://www.reibang.com/p/8a360a3f13aa
關(guān)于select恨课,poll舆乔,epoll3個(gè)網(wǎng)絡(luò)編程異步模型的區(qū)別
http://www.reibang.com/p/3bf72e232fb8