GNU/Linux >> Belajar Linux >  >> Linux

Kirim dan Terima file dalam pemrograman soket di Linux dengan C/C++ (GCC/G++)

Lakukan man 2 sendfile . Anda hanya perlu membuka file sumber di klien dan file tujuan di server, lalu panggil sendfile dan kernel akan memotong dan memindahkan data.


Solusi paling portabel adalah dengan membaca file dalam potongan-potongan, lalu menulis data ke soket, dalam satu lingkaran (dan sebaliknya, saat menerima file). Anda mengalokasikan buffer, read ke dalam buffer itu, dan write dari buffer itu ke soket Anda (Anda juga bisa menggunakan send dan recv , yang merupakan cara menulis dan membaca data khusus soket). Garis besarnya akan terlihat seperti ini:

while (1) {
    // Read data into buffer.  We may not have enough to fill up buffer, so we
    // store how many bytes were actually read in bytes_read.
    int bytes_read = read(input_file, buffer, sizeof(buffer));
    if (bytes_read == 0) // We're done reading from the file
        break;
    
    if (bytes_read < 0) {
        // handle errors
    }
    
    // You need a loop for the write, because not all of the data may be written
    // in one call; write will return how many bytes were written. p keeps
    // track of where in the buffer we are, while we decrement bytes_read
    // to keep track of how many bytes are left to write.
    void *p = buffer;
    while (bytes_read > 0) {
        int bytes_written = write(output_socket, p, bytes_read);
        if (bytes_written <= 0) {
            // handle errors
        }
        bytes_read -= bytes_written;
        p += bytes_written;
    }
}

Pastikan untuk membaca dokumentasi untuk read dan write hati-hati, terutama saat menangani kesalahan. Beberapa kode kesalahan berarti Anda harus mencoba lagi, misalnya mengulang lagi dengan continue pernyataan, sementara yang lain berarti ada sesuatu yang rusak dan Anda harus berhenti.

Untuk mengirim file ke soket, ada panggilan sistem, sendfile itu hanya apa yang Anda inginkan. Ini memberi tahu kernel untuk mengirim file dari satu deskriptor file ke yang lain, dan kemudian kernel dapat menangani sisanya. Ada peringatan bahwa deskriptor file sumber harus mendukung mmap (seperti, jadilah file sebenarnya, bukan soket), dan tujuannya harus berupa soket (sehingga Anda tidak dapat menggunakannya untuk menyalin file, atau mengirim data langsung dari satu soket ke soket lainnya); itu dirancang untuk mendukung penggunaan yang Anda gambarkan, mengirim file ke soket. Namun, itu tidak membantu menerima file; Anda perlu melakukan loop sendiri untuk itu. Saya tidak dapat memberi tahu Anda mengapa ada sendfile panggilan tetapi tidak ada analog recvfile .

Berhati-hatilah dengan sendfile itu apakah Linux spesifik; itu tidak portabel untuk sistem lain. Sistem lain seringkali memiliki versi sendfile mereka sendiri , tetapi antarmuka persisnya mungkin berbeda (FreeBSD, Mac OS X, Solaris).

Di Linux 2.6.17, splice panggilan sistem diperkenalkan, dan mulai 2.6.23 digunakan secara internal untuk mengimplementasikan sendfile . splice adalah API tujuan yang lebih umum daripada sendfile . Untuk deskripsi yang baik tentang splice dan tee , lihat penjelasan yang lumayan bagus dari Linus sendiri. Dia menunjukkan bagaimana menggunakan splice pada dasarnya seperti loop di atas, menggunakan read dan write , kecuali buffer ada di kernel, sehingga data tidak harus ditransfer antara kernel dan ruang pengguna, atau bahkan mungkin tidak pernah melewati CPU (dikenal sebagai "zero-copy I/O").


Linux
  1. Temukan file dan direktori di Linux dengan perintah find

  2. Salin dan tempel di baris perintah Linux dengan xclip

  3. Izin File di Linux dengan Contoh

  1. Skenario Waktu Nyata Linux dan masalah dengan solusinya

  2. Bekerja dengan Input Output dan Error Redirection di Linux

  3. C ++ keamanan utas operator baru di linux dan gcc 4

  1. Temukan File dengan Perintah Temukan dan Temukan di Linux

  2. Cara Mengirim Email Dengan Lampiran dan Isi dari Linux

  3. Howto:Pemrograman C dengan File Sementara di Linux