Soket TCP mengirimkan jumlah byte yang lebih sedikit

Saya mencoba mengirim byte dalam jumlah besar menggunakan perpustakaan boost.asio sebagai berikut:

void tcp_send(boost::asio::io_service &io, const char *dst_ip, uint16 dst_port)
{
    uint8 *sbuff;
    size_t slen;
    ip::tcp::socket sock(io);

    sock.connect(ip::tcp::endpoint(ip::address::from_string(dst_ip), dst_port));

    sbuff = new uint8[100412];
    sbuff[0] = 67;
    sbuff[1] = 193;
    sbuff[2] = 136;
    sbuff[3] = 60;

    boost::asio::async_write(sock, boost::asio::buffer(sbuff, 100412),
             boost::bind((&send_handler), placeholders::error));
}

Ketika saya memeriksa jumlah byte yang dikirimkan menggunakan Wireshark, pengirim selalu mengirimkan dan hanya 65536 byte data tidak termasuk byte header TCP. Jadi apa masalahnya? Apakah ada parameter yang perlu saya ubah.

Saya menjalankan aplikasi di linux ubuntu. Tampaknya jumlah maksimum byte yang dikirimkan adalah 2^16.

Aliran Aliran Wireshark TCP


person IoT    schedule 21.05.2014    source sumber


Jawaban (2)


TCP adalah aliran. Berapa banyak byte yang muncul dalam datagram IP atau frame Ethernet seharusnya tidak menjadi perhatian Anda.

Berhasil memanggil send belum tentu berarti data sudah terkirim; hanya saja tumpukan TCP menerima data dan berjanji untuk mengirimkannya (kecuali Anda menentukan PSH).

person Jonathon Reinhart    schedule 21.05.2014
comment
Jadi apa yang harus saya lakukan agar semua 100412 byte habis? Sebenarnya saya tidak mengalami masalah saat menggunakan soket Berkeley secara langsung, tetapi sekarang saya mengalami masalah dengan pembungkus boost. - person IoT; 22.05.2014
comment
Tidak yakin bagaimana Anda menerapkan sisa barang Anda, tetapi Anda dapat mencoba melacaknya di send_handler. - person Captain Obvlious; 22.05.2014
comment
Tolong bisakah Anda memeriksa hasil edit baru saya, saya memberikan keluaran Wireshark. send_handler hanya untuk penanganan kesalahan - person IoT; 22.05.2014
comment
send_handler dipanggil ketika pengiriman selesai, berhasil atau tidak. Biarkan ia memberi tahu Anda apakah buffer penuh telah dikirim, atau jika pengiriman gagal. Kemungkinannya adalah gagal setelah mengirim 65536 byte. TCP tidak dapat mengirim 100412 byte dalam satu paket, jadi async_write() harus mengirimkan beberapa paket hingga buffer habis atau terjadi kesalahan. - person Remy Lebeau; 22.05.2014
comment
Sekarang saya mencoba mengganti boost::asio::async_write() dengan boost::asio::write, dan operasi berhasil. Saya bisa melihat semua byte di Wireshark. Adakah yang bisa menjelaskan kepada saya apa yang terjadi? @Remy Anda benar, tapi saya tidak mendapatkan kesalahan apa pun di send_handler sama sekali. - person IoT; 22.05.2014

Saya menemukan sumber masalahnya. Pertama-tama, saya mencoba mengirim pesan dengan menggunakan fungsi tcp_Send dan setelah kembali dari panggilan, saya membuat programnya. Karena itu tumpukan TCP tidak mempunyai cukup waktu untuk mengirim semua paket dalam buffernya. Jadi saya harus memberinya waktu.

Sekarang pada percobaan kedua, saya tetap menjalankan aplikasi setelah mengirim pesan, tetapi sekarang saya mendapatkan kesalahan di send_handler, yang menyatakan bad file descriptor. Dan ini karena soket yang dideklarasikan dihancurkan setelah keluar dari fungsi tcp_send. Jadi untuk mengatasi masalah ini saya harus mendefinisikan soket sebagai penunjuk. Atau yang terbaik adalah menggunakan write daripada async_Write

person IoT    schedule 22.05.2014
comment
Itu tidak akan menyebabkan hilangnya data. Ketika Anda menghancurkan ip::tcp::socket, soket yang mendasarinya ditutup tetapi semua data yang tertunda tetap berada di buffer pengiriman soket untuk transmisi akhirnya, diikuti dengan penutupan yang teratur (TCP FIN). Namun mungkin belum semuanya terkirim pada saat program Anda keluar. - person user207421; 22.05.2014
comment
Saya belum mengujinya baru-baru ini, tetapi biasanya di Windows (XP dan sebelumnya) keluar dari suatu proses akan membuang data yang belum terkirim dari tumpukan jaringan, sedangkan pada sistem *nix, data pada akhirnya akan tetap dikirim. PITA nyata untuk pemrogram Windows karena tidak ada cara yang baik untuk menanyakan apakah data benar-benar telah terkirim. - person Dale Wilson; 22.05.2014