ホームページ  >  記事  >  バックエンド開発  >  Pythonネットワークプログラミング学習記(3):ソケットネットワークサーバー

Pythonネットワークプログラミング学習記(3):ソケットネットワークサーバー

WBOY
WBOYオリジナル
2016-06-16 08:43:501391ブラウズ

1、TCP连接的建立方法

客户端在建立一个TCP连接时一般需要两步,而服务器的这个过程需要四步,具体见下面的比较。

步骤 TCP客户端 TCP服务器
第一步 建立socket对象  建立socket对象
第二步 调用connect()建立一个和服务器的连接 设置socket选项(可选)
第三步 绑定到一个端口(也可以是一个指定的网卡)
第四步 侦听连接

下面具体来讲这四步的建立方法:

第一步,建立socket对象:这里与客户端一样,依然是:

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

第二步,设置和得到socket选项

python定义了setsockopt()和getsockopt(),一个是设置选项,一个是得到设置。这里主要使用setsockopt(),具体结构如下:

setsockopt(level,optname,value)

level定义了哪个选项将被使用。通常情况下是SOL_SOCKET,意思是正在使用的socket选项。它还可以通过设置一个特殊协议号码来设置协议选项,然而对于一个给定的操作系统,大多数协议选项都是明确的,所以为了简便,它们很少用于为移动设备设计的应用程序。

optname参数提供使用的特殊选项。关于可用选项的设置,会因为操作系统的不同而有少许不同。如果level选定了SOL_SOCKET,那么一些常用的选项见下表:

选项

意义

期望值

SO_BINDTODEVICE

可以使socket只在某个特殊的网络接口(网卡)有效。也许不能是移动便携设备

一个字符串给出设备的名称或者一个空字符串返回默认值

SO_BROADCAST

允许广播地址发送和接收信息包。只对UDP有效。如何发送和接收广播信息包

布尔型整数

SO_DONTROUTE

禁止通过路由器和网关往外发送信息包。这主要是为了安全而用在以太网上UDP通信的一种方法。不管目的地址使用什么IP地址,都可以防止数据离开本地网络

布尔型整数

SO_KEEPALIVE

可以使TCP通信的信息包保持连续性。这些信息包可以在没有信息传输的时候,使通信的双方确定连接是保持的

布尔型整数

SO_OOBINLINE

可以把收到的不正常数据看成是正常的数据,也就是说会通过一个标准的对recv()的调用来接收这些数据

布尔型整数

SO_REUSEADDR

socket关闭后,本地端用于该socket的端口号立刻就可以被重用。通常来说,只有经过系统定义一段时间后,才能被重用。

布尔型整数



このセクションを学習する際には、SO_REUSEADDR オプションが使用されました。具体的な記述方法は次のとおりです。

S.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) ここの値は 1 に設定されます。これは、サーバー ソケットが閉じられた後、またはサーバー ソケットが閉じられた直後に、SO_REUSEADDR が TRUE としてマークされることを意味します。それ以外の場合、オペレーティング システムはポートを数分間予約します。

次のメソッドは、このシステムで Python によってサポートされるソケット オプションのリストを取得するのに役立ちます:

コードをコピー コードは次のとおりです。

importソケット
solist=[x for x in dir(socket ) if x .startswith('SO_')]
solist.sort()
for x in solist:
Print x

ステップ 3: ソケットをバインドする

バインドにはサーバーのポート番号が必要です。

S.bind((host,port))、host はサーバー IP で、通常は空であるか、特定の IP アドレスにバインドできます。ポートはポート番号です。

ステップ 4: 接続をリッスンします。

listen() 関数を使用して接続をリッスンします。この関数にはパラメーターが 1 つだけあり、サーバーが実際に接続を処理している間にキュー内で待機できる保留 (待機) 接続の数を指定します。慣例として、多くの人はこれを 5 に設定します。例: s.listen(5)

2. シンプルな TCP サーバー インスタンス

これにより、シンプルな TCP サーバーとクライアントが作成されます。

サーバー側: TCP はクライアントとの接続が確立されると、サーバーに応答し、クライアントの IP とポートを表示すると同時に、受信したクライアント情報を「わかりました!」と渡します。現時点では、新しい情報が入力されてクライアントに渡されるのを待っています。

クライアント: TCP クライアント。最初にサーバーの IP アドレスを入力し、次に情報を入力します。Enter を押した後、サーバーから返される情報を取得し、サーバーが情報を送信するのを待ちます。その後終了します。

具体的なコードは次のとおりです:
サーバー側: tcpserver.py

コードをコピー コードは次のとおりです:

# -*-coding: cp936 -*-
## tcp 応答サーバーは、クライアントとの接続を確立した後、クライアントの IP とポートを表示し、同時に受信したクライアント情報をクライアントに渡して「わかりました!」を待ちます。クライアントに渡す新しい情報を入力します。
##@小五义
インポートソケット,トレースバック
ホスト=''
ポート=12345
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s .setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(1)

1 の間:
試行:
Clientsock, ClientAddr = S.Accept ()
KeyboardInterrupt を除く:
RAISE
例外:
Traceback.print_exc () 続行
試行: Print "from:" ", clientsock.getpeername ()
While 1:
Data = Clientsock.recv (4096)
if not len (data ):
BREAK Print Clientsock.getpeername () [0]+':'+Str (データ)
Clientsock.Sendall (データ)
Clientsock.Sendall ("ni get it! n" )
T =raw_input('単語を入力してください:')
clientock.sendall(t)
例外 (KeyboardInterrupt,SystemExit):
raise
例外:
trackback.print_exc( )

try:
clientock.close()

KeyboardInterrupt を除く:

raise
例外:
trackback.print_exc()



クライアント: tcpclient.py

コードをコピー

コードは次のとおりです:

# -*-coding: cp936 -*-
##tcp クライアント、最初にサーバーの IP アドレスを入力し、次に情報を入力して Enter を押すと、サーバーから返される情報が表示されます。その後待ちます。サーバーにメッセージを送信させるため、メッセージの後に終了します。
##@小五义
importソケット,sys
port=12345
host=raw_input('サーバーIPを入力してください:')
data=raw_input('送信する情報を入力してください: ')
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
s.connect((host,port))
以外:
print '接続エラー! '
s.send(data)
s.shutdown(1)
print '送信が完了しました。 '
while 1:
buf=s.recv(4096)
if not len(buf):
Break
sys.stdout.write(buf)

実行結果:

クライアント側で「hello」と入力し、サーバー側で「ok」と入力します。具体的な表示結果は次のとおりです。

サーバー側:

接続元: ('127.0.0.1',1945)
127.0.0.1:hello
ワールドを入力:ok
クライアント:
サーバー IP を入力:127.0.0.1
Enter送信したい情報: こんにちは
送信が完了しました。
こんにちは
わかりました!
わかりました

3. UDP サーバー

UDP サーバーの確立は TCP と似ています。具体的な比較は次のとおりです。

手順

步骤

UDP

TCP

第一步

建立socket对象

建立socket对象

第二步

设置socket选项

设置socket选项

第三步

绑定到一个端口

绑定到一个端口

第四步

Recvfrom()

侦听连接listen

UDP

TCP

最初のステップ

ソケットオブジェクト

を作成しますTD>

ソケットオブジェクト

を作成しますTD>

第 2 ステップ

ソケットオプション

を設定しますTD>

ソケットオプション

を設定しますTD>

第 3 ステップ

ポートにバインド

ポートにバインド

ステップ 4

Recvfrom()

接続をリッスン listen


ここでは UDP を使用してタイムサーバーを確立します。

コードは次のとおりです:

サーバー側;serverudp.py



コードをコピー


コードは次のとおりです:


# -*-coding: cp936 -*-
## UDP サーバー側、クライアントが接続した後、現在の時刻を送信します
##@小五义
importソケット,traceback,time,struct
host=''
port=12345
s=ソケット .socket(socket.AF_INET,socket.SOCK_DGRAM)

s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)s.bind((host,port))

while 1:

try:

message,address=s.recvfrom(8192) secs=int(time.time()) Reply=struct.pack("!I" ,secs) s.sendto(reply,address) (KeyboardInterrupt,SystemExit) を除く: raise
除く:
trackback.print_exc()



クライアント: clientudp.py




コードをコピー

コードは次のとおりです:


# -*-coding: cp936 -*-
## udp client 、サーバーに null 文字を送信した後、サーバーの戻り時間を取得します ##@小五义importソケット,sys,struct,time

host=raw_input('入力サーバーアドレス:' )

port=12345

s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.sendto('',(host,port))
print "応答を待っています.. ."
buf =s.recvfrom(2048)[0]
if len(buf)!=4:

print "応答エラー %d:%s"%(len(buf),buf) sys.exit (1)secs=struct.unpack("!I",buf)[0]print time.ctime(int(secs)) 実行結果: 最初にサーバー側を実行し、次にクライアント側を実行します。 C:>python clientudp.py ##clientudp.py プログラムは C ドライブに保存されています サーバー アドレスを入力してください: 127.0.0.1返信を待っています...月 8 月 6 日 17 :09:17 2012
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。