Pertanyaan Bagaimana cara menutup soket yang dibiarkan terbuka oleh program yang terbunuh?


Saya memiliki aplikasi Python yang membuka soket TCP sederhana untuk berkomunikasi dengan aplikasi Python lain pada host yang terpisah. Kadang-kadang program akan salah atau saya akan langsung membunuhnya, dan dalam kedua kasus soket mungkin dibiarkan terbuka untuk beberapa waktu yang tidak diketahui.

Saat berikutnya saya menjalankan program, saya mendapatkan kesalahan ini:

socket.error: [Errno 98] Address already in use

Sekarang program tersebut selalu mencoba menggunakan port yang sama, sehingga tampak seolah-olah masih terbuka. Saya memeriksa dan yakin programnya tidak berjalan di latar belakang, namun alamat saya masih digunakan.

Jadi, bagaimana saya bisa secara manual (atau tidak) menutup soket / alamat sehingga program saya dapat segera menggunakannya kembali?

Memperbarui

Berdasarkan jawaban Mike saya memeriksanya socket(7) halaman dan melihat SO_REUSEADDR:

SO_REUSEADDR
    Indicates that the rules used in validating addresses supplied in a bind(2) call should
    allow reuse of local addresses.  For AF_INET sockets this means that a socket may bind,
    except when there is an active listening socket bound to the address.  When the listen‐
    ing  socket is bound to INADDR_ANY with a specific port then it is not possible to bind
    to this port for any local address.  Argument is an integer boolean flag.

32
2018-05-03 14:14


asal


Jawaban:


Asumsikan soket Anda diberi nama s... Anda perlu mengatur socket.SO_REUSEADDR pada soket server sebelum mengikat ke antarmuka ... ini akan memungkinkan Anda untuk segera me-restart server TCP ...

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ADDR, PORT))

33
2018-05-03 15:00



Anda mungkin ingin mencoba menggunakan Twisted untuk jaringan Anda. Mike memberi jawaban tingkat rendah yang benar, SO_REUSEADDR, tetapi dia tidak menyebutkan bahwa ini bukan pilihan yang sangat baik untuk mengatur pada Windows. Ini adalah hal yang Twisted rawat untuk Anda secara otomatis. Ada banyak, banyak contoh lain dari detail tingkat rendah membosankan seperti ini yang harus Anda perhatikan ketika menggunakan modul soket secara langsung tetapi yang dapat Anda lupakan jika Anda menggunakan perpustakaan tingkat yang lebih tinggi seperti Twisted.


10
2018-05-04 01:04



Anda membingungkan soket, koneksi, dan port. Soket adalah titik akhir koneksi, yang pada gilirannya adalah 5-tupel {protocol, local-ip, local-port, remote-ip, remote-port}. Soket program yang terbunuh telah ditutup oleh OS, dan ke koneksi. Satu-satunya peninggalan dari koneksi adalah soket peer dan port yang sesuai di host peer. Jadi apa yang seharusnya Anda tanyakan adalah bagaimana menggunakan kembali lokal Pelabuhan. Yang jawabannya adalah SO_REUSEADDR sesuai jawaban yang lain.


3
2018-05-04 10:33