Pythonのソケットプログラミング
サーバー
#!/usr/bin/env python
# coding=utf-8
from socket import *
HOST = ''
PORT = 2345
BUFSIZE = 1024
ADDR = (HOST,PORT)
#创建AF_INET地址族,TCP的套接字
with socket(AF_INET,SOCK_STREAM) as tcpSerSock:
#绑定ip和端口
tcpSerSock.bind(ADDR)
#监听端口,是否有请求
tcpSerSock.listen(5)
while True:
print("waiting for connect!!")
#accept() 是阻塞的
tcpClientSock,addr = tcpSerSock.accept()
print("the client: ",addr,"is connecting")
with tcpClientSock:
#使用一个while循环,持续和客户端通信,直到客户端断开连接或者崩溃
while True:
data = tcpClientSock.recv(BUFSIZE)
#判断客户端是否断开连接
if not data:
break;
print("client: ",data.decode("utf-8"))
#相应客户端请求
msg = input("server: ")
tcpClientSock.sendall(msg.encode("utf-8"))
#客户端退出
print("client ",addr,"exit!")
クライアント
#!/usr/bin/env python
# coding=utf-8
from socket import *
HOST = "192.168.8.188"
# HOST = "127.0.0.1"
PORT = 2345
ADDR = (HOST,PORT)
with socket(AF_INET,SOCK_STREAM) as tcpCliSock:
tcpCliSock.connect(ADDR)
with tcpCliSock:
while True:
msg = input("client:")
tcpCliSock.sendall(msg.encode('utf-8'))
data=tcpCliSock.recv(1024)
if not data:
break
print("server: ",data.decode("utf-8"))
print("server crash")
サーバプロセスとクライアントプロセスを開始します
python server.py
python client.py
次のように通信結果は以下の通りでした。
netstatコマンド
netstatコマンドは、そのソケット情報のステータスを表示
しますが、TCPを介した接続を確立するために、クライアント・プロセスとサーバ・プロセスの結果を見ることができるように
ISOF
コマンドは、PID(プロセスID)とユーザ(ユーザID)、-iコマンドISOF以下の出力パラメータは、オープンソケット接続がマニュアルlsofをすることにより、クライアントの印刷情報に接続されている表示することができ、詳細を確認
tcpdumpを
tcpdumpのパケットキャプチャ、ポート番号があるので、2345であるtcpdumpのパラメータは、ポート番号に設定することができるので、詳細なパラメータは、自己百度とすることができる
通信手順の上方に、tcpdumpのキャプチャポート番号を見ることができる図に沿ったものです。
コントラストPythonのソケットAPIとLinuxのソケットAPI
使用のstraceコマンドトレースの比較は、PythonのAPIは、LinuxパッケージのAPIで、見つけました。
strace python ./client.py
パイソン | Linuxの |
---|---|
ソケット(AF_INET、SOCK_STREAM) | ソケット(PF_INET、SOCK_STREAM、IPPRPTO_IP)= 3 |
バインド((ホスト、ポート)) | バインド(3、{sa_familyに= AF_INET、sin_portは= htons(2345)、sin_addr( "0.0.0.0")}、16)= 0 |
受け入れます() | 受け入れ(3、{sa_familyに= AF_INET、sin_portは= htons(2345)、sin_addr(「192.168.8.xx)}、[16]))= 4 |
RECV(BUFERSIZE) | recvfrom(4、buf_address、レンス、0、NULL、NULL) |
sendall(msg.encode( "UTF-8)) | sendto(4,msg,sizeof(msg),0,NULL,0) |
connect((host,port)) | connect(3,{sa_family=AF_INET,sin_port=htons(2345),sin_addr("192.168.8.xx)},[16]))=4 |
表格中的3 ,4表示文件描述符,熟悉linux系统的朋友对文件描述符想必不会陌生,但可以注意到服务器进程产生了两个文件描述符,先是一个3,对应socket创建,而后accept之后,又产生了一个文件描述符4,对应客户端;而客户端始终只有一个3,对应当前连接,可以看到二者的文件描述符是无必然相等关系的。