GNU/Linux >> Belajar Linux >  >> Linux

Mengapa connect() memberikan EADDRNOTAVAIL?

Periksa tautan ini

http://www.toptip.ca/2010/02/linux-eaddrnotavail-address-not.html

EDIT :Ya saya bermaksud menambahkan lebih banyak tetapi harus memotongnya di sana karena keadaan darurat

Apakah Anda menutup soket sebelum mencoba menyambung kembali? Menutup akan memberi tahu sistem bahwa pasangan soket (ip/port) sekarang gratis.

Berikut adalah item tambahan yang juga dilihat:

  • Jika port lokal sudah terhubung ke IP dan port jarak jauh yang diberikan (yaitu, sudah ada pasangan soket yang identik), Anda akan menerima kesalahan ini (lihat tautan bug di bawah).
  • Mengikat alamat soket yang bukan alamat lokal akan menghasilkan kesalahan ini. jika alamat IP mesin adalah 127.0.0.1 dan 1.2.3.4, dan Anda mencoba mengikat ke 1.2.3.5, Anda akan mendapatkan kesalahan ini.
  • EADDRNOTAVAIL:Alamat yang ditentukan tidak tersedia di mesin jarak jauh atau bidang alamat struktur nama semuanya nol.

Tautkan dengan bug yang mirip dengan milik Anda (jawabannya dekat dengan bagian bawah)

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4294599

Tampaknya soket Anda pada dasarnya macet di salah satu status internal TCP dan menambahkan penundaan untuk penyambungan kembali dapat menyelesaikan masalah Anda seperti yang tampaknya telah dilakukan dalam laporan bug tersebut.


Jika Anda tidak ingin mengubah jumlah port sementara yang tersedia (seperti yang disarankan oleh David), atau Anda memerlukan lebih banyak koneksi daripada jumlah maksimum teoretis, ada dua metode lain untuk mengurangi jumlah port yang digunakan. Namun, mereka melakukan berbagai pelanggaran terhadap standar TCP, sehingga harus digunakan dengan hati-hati.

Yang pertama adalah mengaktifkan SO_LINGER dengan batas waktu nol detik, memaksa TCP tumpukan untuk mengirim paket RST dan mengosongkan status koneksi. Namun ada satu kehalusan:Anda harus memanggil shutdown pada deskriptor file soket sebelum Anda close , sehingga Anda memiliki kesempatan untuk mengirim FIN paket sebelum RST paket. Jadi kodenya akan terlihat seperti:

shutdown(fd, SHUT_RDWR);
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
// todo: test for error
setsockopt(fd, SOL_SOCKET, SO_LINGER,
           (char *) &linger, sizeof(linger));
close(fd);

Server seharusnya hanya melihat koneksi prematur yang disetel ulang jika FIN paket disusun ulang dengan RST paket.

Lihat opsi TCP SO_LINGER (nol) - bila diperlukan untuk detail lebih lanjut. (Secara eksperimental, tidak masalah di mana Anda menyetel setsockopt .)

Yang kedua adalah menggunakan SO_REUSEADDR dan bind eksplisit (bahkan jika Anda adalah kliennya), yang akan memungkinkan Linux untuk menggunakan kembali porta sementara saat Anda menjalankannya, sebelum selesai menunggu. Perhatikan bahwa Anda harus gunakan bind dengan INADDR_ANY dan port 0 , jika tidak SO_REUSEADDR tidak dihormati. Kode Anda akan terlihat seperti:

int opts = 1;
// todo: test for error
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
         (char *) &opts, sizeof(int));

struct sockaddr_in listen_addr;
listen_addr.sin_family = AF_INET;
listen_addr.sin_port = 0;
listen_addr.sin_addr.s_addr = INADDR_ANY;
// todo: test for error
bind(fd, (struct sockaddr *) &listen_addr, sizeof(listen_addr));

// todo: test for addr
// saddr is the struct sockaddr_in you're connecting to
connect(fd, (struct sockaddr *) &saddr, sizeof(saddr));

Opsi ini kurang bagus karena Anda masih akan memenuhi struktur data kernel internal untuk koneksi TCP sesuai netstat -an | grep -e tcp -e udp | wc -l . Namun, Anda tidak akan mulai menggunakan kembali port hingga hal ini terjadi.


Ini juga dapat terjadi jika port yang diberikan tidak valid, seperti 0.


Linux
  1. Mengapa Anda mendapatkan cp:menghilangkan kesalahan direktori di Linux dan bagaimana mengatasinya

  2. Mengapa `md5sum` Tidak Memberikan Hash yang Sama Seperti Internet?

  3. Ssh – Mengapa Ssh Membutuhkan Waktu Lama Untuk Terhubung?

  1. Tidak dapat terhubung ke kesalahan server MySQL 111

  2. Mengapa ENOENT berarti Tidak ada file atau direktori seperti itu?

  3. mengapa saya mendapatkan kesalahan format Exec saat menulis layanan linux saya?

  1. apache2.4 dengan webdav memberikan kesalahan 405

  2. Mengapa seseorang memilih FreeBSD daripada Linux?

  3. Mengapa seseorang ingin menjalankan UserMode Linux (UML)