転載:https://www.cnblogs.com/xiaowenshu/p/9916755.html
一般に「ソケット」と呼ばれるソケットをIPアドレスとポートを記述するために使用され、通信リンクがハンドルである、アプリケーションは、通常、「ソケット」ネットワーク要求または応答を介してネットワークへの要求を発行します。
ソケットは、Unixの起源、およびUnix / Linuxの基本理念の一つは、モード動作を読み書きする[] [] [閉じる]ファイルを開くには、「すべてはファイルである」です。ソケットは、モデルの実現である、ソケットは特別なファイルで、そのうちのいくつかのオペレーティング・ソケット機能が実行される(オープン、読み込み/ IOを書き、閉じた状態)。
ソケットとファイルの違い:
ファイルには、2つのプロセス間でデータを転送する、同じコンピュータ上のすべてのです。
ソケットは、別のコンピュータ、すなわち、ネットワーク・トラフィックとの間のデータの伝送に実装されてもよいです。たとえば、QQ、Webページを開く、これらの通信を達成するためのソケットです。
それは、TCP / IP、UDPプロトコルとプロトコル、直接に良いパッケージUPDおよびTCP / IPプロトコルを持つソケットが来ることを、ネットワーク通信も。
単にプロトコルがやっているTCP / IPの下で、ネットワークはちょうど、混乱を出てきた、と我々はすべてのルールを遵守するためのデータを転送する必要があることを、我々はすべて、これは、その後、TCP / IPプロトコルが登場従ってください。たぶん、あなたは4回オフ、3ウェイハンドシェイクのことを聞いた、それは、TCP / IP接続のプロセスです。コンピュータ通信およびBにコンピュータを追加し、プロセスはそのようになっています
A:それには、私もあなたが行うことができない
B:あなたもそれ、中
:まあ、私はあなたにデータを送信するつもりです
#これは、2台のコンピュータが再び通行することができ、良好なチャネルを確立して3ウェイハンドシェイク、です。
だから、4回オフするものです
A:私はあなたを離れたい
B:さて、あなたはそれを抜い
B:チャンネル閉じ
チャンネルを閉じます:
データ転送が互いに終了するので、我々は、2つのパスを掘っ理由オフ回、一方の経路が他方にB、Bにデータを送信するために使用されるデータ転送には、各々がそれぞれのチャネルを閉じる、二回オフされています。2本の道路は、サブと呼ばれる全二重、すなわち、両側に片側のみがデータを送信できる場合、それは単純呼ばれ、相互にデータを送信することができるあります。
以下の図は、あなたがデータ接続および送信プロセスを確立するプロセス、及び切断処理を見ることができます。
そして、UDPプロトコルは、比較的単純な、あまり複雑で切断し、接続され、3ウェイハンドシェイクを必要としない、クライアントは、サーバーが受信できるかどうかを判断する必要はありません、TCP / IPは、データを送信するために良好な接続後に確立されなければなりません、そしてそれが直接送信されたIPとポート番号を知っているUDP接続は、それはTCP / IPよりも速いが、安全ではない、ではありません。
UPD道路にできるだけ書くのが好き、他の当事者受け取っていないがありません。TCP / IP呼びたい、あなたが話すようになっている必要があります。
以下は、UDPサーバー側のコードです:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import socket
'''
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。
虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
我们来看看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口
绑定端口和TCP一样,但是不需要调用listen()方法,而是直接接收来自任何客户端的数据
'''
# ipv4 SOCK_DGRAM指定了这个Socket的类型是UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定 客户端口和地址:
s.bind(('127.0.0.1', 9999))#绑定9999端口号
print('开始聊天了')
while True:
# 接收数据 自动阻塞 等待客户端请求:
data, addr = s.recvfrom(1024) #接收客户端发过来的数据和ip地址
data = data.decode()
print('客户端的ip信息',addr)
print('发过来的数据 %s'%data)
msg = input('你的回复:') #这个是咱们返回的数据
s.sendto(msg.encode(), addr)#把数据发送给客户端
# recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。
|
以下は、クライアント側のコードです
1
2
3
4
5
6
7
8
9
10
11
12
|
import socket
'''
客户端使用UDP时,首先仍然创建基于UDP的Socket,然后不需要连接,直接通过sendto()给服务器发数据:
'''
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data = input('data:')
s.sendto(data.encode(), ('127.0.0.1', 9999))#
# 发送数据:
recv = s.recv(1024) #返回的数据
print(recv.decode())
# 接收数据:
s.close()
|
サーバー側のコードの実行クライアントがバックデータにサーバ側、サーバー側にデータを送り、実行し、その結果、以下の簡単なチャットアプレットを実行します
ここでは、コードのTCP / IPプロトコル、サーバー側のコードは次のとおりです。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #建立一个tcp/ip scoket
sock.bind(('127.0.0.1',9999)) #绑定端口号
sock.listen(128)#监听,同时能连多少个客户端
while True:
print('开始等待下一个客户端过来。。。')
client,addr = sock.accept() #接收到客户端的socket,和地址
print('接收到 client数据',addr)
while True:
#
data = client.recv(1024)#获取到客户端的数据
data = data.decode()
if not data or data=='bye':
#如果没有发送过来数据就代表客户端close了,或者发过来bye代表连接要断开
print('服务结束',addr)
client.close()#断开连接,为下一个服务
break
else:#如果他还在发送的话
print('发过来的', data)
msg = input('回复:')
client.send(msg.encode()) # 数据
sock.close()
|
#以下は、クライアント側のコード接続サービスであります
1
2
3
4
5
6
7
8
9
10
11
12
|
import socket
s = socket.socket()
s.connect(('127.0.0.1',9999)) #连接服务端
while True:#
data = input('data:')
s.send(data.encode())#发送数据
recv = s.recv(1024).decode()
print(recv)
if data=='close':
break
s.close()
|
あなたは、これは実際には、それを暗く学びたいと思うかもしれませんが、実装の基礎となるこれらのWebフレームワークは、例えば、ジャンゴ、ソケットになりフラスコのために、我々はまた、独自のWebフレームワークを開発することができ、そうです。もちろん、提供することができ、マルチスレッドやマルチプロセスの複数のクライアントを持つクライアントに、今だけのサービス、。
サーバーは、結果を実行します
マルチスレッド以下、毎回クライアントを使用すると、複数のクライアントにサービスを提供できるように、次のようにしても、彼のサービスのためのスレッドを開始する要求にモジュールをねじ込むことによって、スレッドを開始し、サービスのスレッドを開始してきました:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import socket,threading
class SocketServer:
def __init__(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立一个tcp/ip scoket
sock.bind(('127.0.0.1', 9999)) # 绑定端口号
sock.listen(128) # 监听
self.sock = sock
def start_server(self):
while True:
print('开始等待个客户端过来')
client,addr = self.sock.accept()
print('客户【%s】过来了',addr)
t = threading.Thread(target=self.client_recv,args=(client,addr))
t.start()
def client_recv(self,client,addr):
while True:
data = client.recv(1024) # 获取到客户端的数据
data = data.decode()
if not data or data == 'bye':
# 如果没有发送过来数据就代表客户端close了,或者发过来bye代表连接要断开
print('服务结束', addr)
client.close() # 断开连接,为下一个服务
break
else: # 如果他还在发送的话
print('发过来的', data)
msg = '统一回复,人不在'
client.send(msg.encode()) # 数据
if __name__ == '__main__':
t = SocketServer()
t.start_server()
|