回答編集履歴
3
コードの修正
test
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
udpのsocketをnon blockingにし,add_readerでイベントを登録することで実装できました.
|
2
|
-
**ちなみにwindowsでは,asyncio.get_event_loop()が使えないようです.**
|
2
|
+
**ちなみに私の環境であるwindowsでは,asyncio.get_event_loop()が使えないようなので代替記法で書いています.**
|
3
3
|
|
4
4
|
本質問では,UDPで受信した後,TCPで返送するプログラムでしたがTCP部分が正常に動かなかったため.TCPの部分は削除しました.
|
5
5
|
|
@@ -59,6 +59,7 @@
|
|
59
59
|
|
60
60
|
|
61
61
|
# イベントループの取得 & セット
|
62
|
+
# 以下3行は,windows以外なら,asyncio.get_event_loop() のみで良い
|
62
63
|
selector = selectors.SelectSelector()
|
63
64
|
loop = asyncio.SelectorEventLoop(selector)
|
64
65
|
asyncio.set_event_loop(loop)
|
2
コードの修正
test
CHANGED
@@ -18,7 +18,9 @@
|
|
18
18
|
# 自分の送ったマルチキャストパケットを自身で受け取らない
|
19
19
|
udp_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
|
20
20
|
udp_sock.bind(('', PORT))
|
21
|
+
|
22
|
+
# ノンブロッキングに指定
|
21
|
-
udp_sock.set
|
23
|
+
udp_sock.setblocking(False)
|
22
24
|
|
23
25
|
|
24
26
|
FILE_NAME = 'send.txt'
|
@@ -56,15 +58,17 @@
|
|
56
58
|
time.sleep(0.05)
|
57
59
|
|
58
60
|
|
59
|
-
#
|
61
|
+
# イベントループの取得 & セット
|
60
|
-
|
62
|
+
selector = selectors.SelectSelector()
|
61
|
-
|
63
|
+
loop = asyncio.SelectorEventLoop(selector)
|
62
|
-
|
64
|
+
asyncio.set_event_loop(loop)
|
63
65
|
|
66
|
+
# udp_sockのファイルディスクリプタが空いたら,紐づけられた関数を実行
|
64
|
-
|
67
|
+
loop.add_reader(udp_sock.fileno(), recv_loss_packet)
|
65
68
|
|
69
|
+
# ループを回す
|
66
|
-
|
70
|
+
try:
|
67
|
-
|
71
|
+
loop.run_forever()
|
68
|
-
|
72
|
+
finally:
|
69
|
-
|
73
|
+
loop.close()
|
70
74
|
```
|
1
ソースの変更
test
CHANGED
@@ -1,20 +1,70 @@
|
|
1
1
|
udpのsocketをnon blockingにし,add_readerでイベントを登録することで実装できました.
|
2
|
-
ちなみにwindowsでは,asyncio.get_event_loop()が使えないようです.
|
2
|
+
**ちなみにwindowsでは,asyncio.get_event_loop()が使えないようです.**
|
3
|
+
|
4
|
+
本質問では,UDPで受信した後,TCPで返送するプログラムでしたがTCP部分が正常に動かなかったため.TCPの部分は削除しました.
|
3
5
|
|
4
6
|
```async.py
|
7
|
+
M_Group = "239.1.2.3"
|
8
|
+
LOCALHOST = socket.gethostbyname(socket.gethostname())
|
5
|
-
|
9
|
+
PORT = 1234
|
6
|
-
import asyncio
|
7
|
-
import selectors
|
8
10
|
|
9
|
-
#
|
11
|
+
# UDPソケットの設定
|
10
|
-
s
|
12
|
+
udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
13
|
+
udp_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(LOCALHOST))
|
14
|
+
udp_sock.setsockopt(
|
15
|
+
socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP,
|
11
|
-
|
16
|
+
socket.inet_aton(M_Group) + socket.inet_aton(LOCALHOST)
|
17
|
+
)
|
18
|
+
# 自分の送ったマルチキャストパケットを自身で受け取らない
|
19
|
+
udp_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
|
20
|
+
udp_sock.bind(('', PORT))
|
12
|
-
|
21
|
+
udp_sock.settimeout(5)
|
13
22
|
|
14
|
-
loop.add_reader(udp_sock.fileno(), recv_loss_packet)
|
15
23
|
|
24
|
+
FILE_NAME = 'send.txt'
|
25
|
+
file_data = ""
|
26
|
+
len_data = 0
|
27
|
+
|
28
|
+
with open(FILE_NAME, 'r') as f:
|
29
|
+
file_data = f.read()
|
30
|
+
len_data = len(file_data)
|
31
|
+
|
32
|
+
|
33
|
+
def recv_loss_packet():
|
34
|
+
|
35
|
+
print("time to wait for response...")
|
16
|
-
try:
|
36
|
+
try:
|
37
|
+
res_data, (src_ip, src_port) = udp_sock.recvfrom(1024)
|
38
|
+
|
39
|
+
print(f'src_ip: {src_ip}, src_port: {src_port}')
|
40
|
+
|
41
|
+
except:
|
42
|
+
print(f"Timeout!")
|
43
|
+
|
44
|
+
|
45
|
+
count = 0
|
46
|
+
|
47
|
+
# データを指定バイトごとに分割
|
48
|
+
chunks = [file_data[i:i+10] for i in range(0, len_data, 10)]
|
49
|
+
|
50
|
+
for chunk in chunks:
|
51
|
+
count+=1
|
52
|
+
chunk = str(count) + ":" + chunk
|
53
|
+
print(chunk)
|
54
|
+
|
55
|
+
udp_sock.sendto(chunk.encode(), (M_Group, PORT))
|
56
|
+
time.sleep(0.05)
|
57
|
+
|
58
|
+
|
59
|
+
# + 追加した部分
|
60
|
+
+ selector = selectors.SelectSelector()
|
61
|
+
+ loop = asyncio.SelectorEventLoop(selector)
|
62
|
+
+ asyncio.set_event_loop(loop)
|
63
|
+
|
64
|
+
+ loop.add_reader(udp_sock.fileno(), recv_loss_packet)
|
65
|
+
|
66
|
+
+ try:
|
17
|
-
loop.run_forever()
|
67
|
+
+ loop.run_forever()
|
18
|
-
finally:
|
68
|
+
+ finally:
|
19
|
-
|
69
|
+
+ loop.close()
|
20
70
|
```
|