質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

Q&A

解決済

1回答

1136閲覧

Python Threadingを使ったtcpソケットをclose()できない

Yochyee

総合スコア2

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

TCP

TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

0グッド

0クリップ

投稿2022/12/28 09:58

実現したいこと

複数(5台)のクライアントとサーバでtcp通信を行っています.プログラムの流れとしては,
(1)クライアントからサーバに対し,connect
(2)サーバは,クライアントからデータを受信
(3)サーバは,クライアントにデータを返信
(4)サーバは,tcpコネクションをclose ← 不具合

発生している問題・エラーメッセージ

適切にclose出来ないだけで,サーバ⇔クライアント間のデータ受信は,問題なく出来ています.

server.py

1ソケット以外のものに対して操作を実行しようとしました。

該当のソースコード

一応全てのソースコードを貼っていますが,関係ないと思われるところは,"~~ 無視 ~~"で囲んであります.

この質問に関する該当コードは,90行目からです.クライアントとコネクションを生成したら別スレッドでrecvし,クライアントにデータを返送しています.
そして別スレッド内でsock.close()を行うとエラーメッセージが発生します.

server.py

1import socket 2import time 3from math import ceil 4import threading 5 6 7M_Group = "239.1.2.3" 8LOCALHOST = socket.gethostbyname(socket.gethostname()) 9PORT = 1234 10 11# UDP Setting 12udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 13udp_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF, socket.inet_aton(LOCALHOST)) 14udp_sock.setsockopt( 15 socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, 16 socket.inet_aton(M_Group) + socket.inet_aton(LOCALHOST) 17) 18# 自分の送ったマルチキャストパケットを自身で受け取らない 19udp_sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0) 20 21 22# TCP Setting 23tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 24tcp_sock.bind((LOCALHOST, PORT)) 25tcp_sock.listen(10) 26 27 28start = 0 29FILE_NAME = 'send_100.txt' 30file_d = "" 31len_d = 0 32 33with open(FILE_NAME, 'r') as f: 34 file_d = f.read() 35 len_d = len(file_d) 36 37 38~~~~~~~~~~~~~無視~~~~~~~~~~~~~~~~~~~~~~~~~~~ 39count=0 40# chunks = [data[i:i+1000] for i in range(0, len(data), 1000)] 41chunks = [file_d[i:i+10] for i in range(0, len_d, 10)] 42max_seq = str(ceil(len_d / 10)) 43 44start = time.time() 45for chunk in chunks: 46 count+=1 47 chunk = max_seq + ":" + str(count) + ":" + chunk 48 49 # udp_sock.sendto(chunk.encode(), (M_Group, PORT)) 50 # time.sleep(0.001) 51 52 # 2個パケットロスを発生 53 if count == 3 or count == 6: 54 continue 55 else: 56 print(chunk) 57 udp_sock.sendto(chunk.encode(), (M_Group, PORT)) 58 time.sleep(0.001) 59 60~~~~~~~~~~~~~無視~~~~~~~~~~~~~~~~~~~~~~~~~~~ 61 62 63# データ受信ループ関数 64def recv_client(sock, addr): 65 recv_seq_ary = [] 66 67 while sock: 68 res_data = sock.recv(1024) 69 70 recv_seq_ary = res_data.decode().split(",") 71 recv_seq_ary.pop(-1) 72 73 recv_seq_ary = list(map(int, recv_seq_ary)) 74 print(recv_seq_ary) 75 76 for i in recv_seq_ary: 77 # chunk = data[(i-1)*1000:(i-1)*1000+1000] 78 chunk = file_d[(i-1)*10:(i-1)*10+10] 79 chunk = str(i) + ":" + chunk 80 81 print(chunk) 82 sock.send(chunk.encode()) 83 84 try: 85 sock.close() 86 except: 87 print("エラー") 88 89# 複数のクライアントとtcpで送受信 90while True: 91 client, addr = tcp_sock.accept() 92 print("client connected...") 93 94 thread = threading.Thread(target=recv_client, args=(client, addr)) 95 96 thread.start() 97 98 99print(time.time() - start) 100

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

socketをcloseしただけでは、while sockの条件は成立するままだから、自分でsockにNoneとかを代入しないとダメ

>>> s = socket.socket() >>> if(s): print(s) <socket.socket fd=428,... >>> s.close() >>> if(s): print(s) <socket.socket [closed] fd = -1, ...> >>> s.recv(1024) OSError: [WinError 10038] ソケット以外のものに対して操作を実行しようとしました。

投稿2022/12/28 10:22

matukeso

総合スコア1590

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yochyee

2022/12/28 10:34

初歩的なミスでした... 指摘ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問