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 によってサポートされるソケット オプションのリストを取得するのに役立ちます:
ステップ 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
1 の間:
試行:
Clientsock, ClientAddr = S.Accept ()
KeyboardInterrupt を除く:
RAISE
例外:
Traceback.print_exc () 続行
試行:
While 1:
Data = Clientsock.recv (4096)
if not len (data ):
BREAK
Clientsock.Sendall (データ)
Clientsock.Sendall ("ni get it! n" )
T =raw_input('単語を入力してください:')
clientock.sendall(t)
例外 (KeyboardInterrupt,SystemExit):
raise
例外:
trackback.print_exc( )
try:
clientock.close()
raise
例外:
trackback.print_exc()
クライアント: tcpclient.py
コードをコピー
実行結果:
クライアント側で「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 |
|||||||||||||||
最初のステップ |
ソケットオブジェクト を作成しますTD> |
ソケットオブジェクト を作成しますTD> |
|||||||||||||||
第 2 ステップ |
ソケットオプション を設定しますTD> |
ソケットオプション を設定しますTD> |
|||||||||||||||
第 3 ステップ |
ポートにバインド |
ポートにバインド |
|||||||||||||||
ステップ 4 |
Recvfrom() |
接続をリッスン listen |
コードは次のとおりです:
# -*-coding: cp936 -*-
## UDP サーバー側、クライアントが接続した後、現在の時刻を送信します
##@小五义
importソケット,traceback,time,struct
host=''
port=12345
s=ソケット .socket(socket.AF_INET,socket.SOCK_DGRAM)
while 1:
try:
host=raw_input('入力サーバーアドレス:' )
port=12345s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
s.sendto('',(host,port))
print "応答を待っています.. ."
buf =s.recvfrom(2048)[0]
if len(buf)!=4: