偽代碼:
ss = socket() #創建服務器套接字
ss.bind() #把地址綁定到套接字上
ss.listen() #監聽連接(最大連接數)
info_loop: #服務器無限循環
cs = ss.accept() #接受客戶端連接
comm_loop: #通信循環
cs.recv()/cs.send() #對話(接收/發送)
cs.close() #關閉客戶端套接字
ss.close() #關閉服務器
所有的套接字都用socket.socket()函數來創建,服務器需要“坐在某個端口上“等待請求”所以它們必須要“綁定”到一個本地地址上,
由于TCP是一個面向連接的通信系統,在TCP服務器開始工作之前,要先完成一些設置,TCP服務器必須“監聽”連接,設置完成之后服務器
就可以進入無限循環了。
一個簡單的“單線程”服務器會調用accept()函數等待連接的到來,默認情況下accept()函數是阻塞的,即程序在連接到來之前會處于掛起狀態,
套接字也支持非阻塞模式。
一旦接收到一個連接,accept()函數就會返回一個單獨的客戶端套接字用于后續的通信。
簡單的TCP服務器
代碼如下
#!/usr/bin/env python3#-*- coding:utf-8 -*-
from socket import *
from time importctime
host= ''port= 12345buffsize= 2048ADDR=(host,port)
tctime=socket(AF_INET,SOCK_STREAM)
tctime.bind(ADDR)
tctime.listen(3)whileTrue:print('Wait for connection ...')
tctimeClient,addr=tctime.accept()print("Connection from :",addr)whileTrue:
data=tctimeClient.recv(buffsize).decode()if notdata:breaktctimeClient.send(('[%s] %s' %(ctime(),data)).encode())
tctimeClient.close()
tctimeClient.close()
TCP客戶端代碼:
#!/usr/bin/env python3#-*- coding:utf-8 -*-
from socket import *HOST='localhost'PORT= 12345BUFFSIZE=2048ADDR=(HOST,PORT)
tctimeClient=socket(AF_INET,SOCK_STREAM)
tctimeClient.connect(ADDR)whileTrue:
data= input(">")if notdata:breaktctimeClient.send(data.encode())
data=tctimeClient.recv(BUFFSIZE).decode()if notdata:break
print(data)
tctimeClient.close()
note:
如果實在ubuntu下面做練習,需要在防火墻上添加allow條目,具體命令是
ufw allow 12345/tcp
也可以直接關閉防火:
ufw disable