发送和C接收套接字编程文件中的Linux / C ++(GCC / G ++) [英] Send and Receive a file in socket programming in Linux with C/C++ (GCC/G++)

查看:148
本文介绍了发送和C接收套接字编程文件中的Linux / C ++(GCC / G ++)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现在使用Linux套接字和C / C ++语言,能够发送和接收文件上运行的客户端 - 服务器架构。有没有使这个任务很容易的图书馆吗?任何人都可以请提供一个例子吗?

I would like to implement a client-server architecture running on Linux using sockets and C/C++ language that is capable of sending and receiving files. Is there any library that makes this task easy? Could anyone please provide an example?

推荐答案

最轻便的解决方案仅仅是读取数据块的文件,然后将数据写入到插座,在一个循环(同样地,另一路围绕接收文件时)。您分配一个缓冲区, 成缓冲区和 缓冲到您的插座(你也可以使用发送的recv ,这是写入和读取数据的特定套接字方式)。大纲会是这个样子:

The most portable solution is just to read the file in chunks, and then write the data out to the socket, in a loop (and likewise, the other way around when receiving the file). You allocate a buffer, read into that buffer, and write from that buffer into your socket (you could also use send and recv, which are socket-specific ways of writing and reading data). The outline would look something like this:

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;
    }
}

请务必阅读文档阅读小心,尤其是操作时的错误。有些错误codeS的意思是,你应该再去尝试,例如只需用继续语句再次循环,而另一些人意味着什么坏了,你需要停止

Make sure to read the documentation for read and write carefully, especially when handling errors. Some of the error codes mean that you should just try again, for instance just looping again with a continue statement, while others mean something is broken and you need to stop.

有关该文件发送到插座,有一个系统调用,<一href=\"http://www.kernel.org/doc/man-pages/online/pages/man2/sendfile.2.html\"><$c$c>sendfile ,不只是你想要的。它告诉内核从一个文件描述符文件发送到另一个,然后内核就可以照顾休息。有一个警告源文件描述符必须支持 MMAP (如,是一个实际的文件,而不是一个插座),目标必须是一个插座(这样​​你就可以'T用它来复制文件,或直接从一个插座发送数据到另一个);它被设计成支持发送文件到一个插座的您所描述的使用情况。它不但是接收文件,帮助;你需要自己做循环了点。我不能告诉你为什么有一个发送文件呼叫,但没有类似 recvfile

For sending the file to a socket, there is a system call, sendfile that does just what you want. It tells the kernel to send a file from one file descriptor to another, and then the kernel can take care of the rest. There is a caveat that the source file descriptor must support mmap (as in, be an actual file, not a socket), and the destination must be a socket (so you can't use it to copy files, or send data directly from one socket to another); it is designed to support the usage you describe, of sending a file to a socket. It doesn't help with receiving the file, however; you would need to do the loop yourself for that. I cannot tell you why there is a sendfile call but no analogous recvfile.

要注意的是发送文件是Linux特有的;它是不能移植到其它系统。其他系统通常有自己的发送文件的版本,但确切的接口可能会有所不同(的 FreeBSD的,<一个href=\"http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man2/sendfile.2.html\">Mac OS X ,<一个href=\"http://docs.oracle.com/cd/E23824_01/html/821-1467/sendfile-3ext.html#scrolltoc\">Solaris).

Beware that sendfile is Linux specific; it is not portable to other systems. Other systems frequently have their own version of sendfile, but the exact interface may vary (FreeBSD, Mac OS X, Solaris).

在Linux的2.6.17中, 拼接 系统调用是介绍以及为2.6.23是的内部使用,用于执行发送文件 拼接是一个比较通用的API比发送文件。对于的一个很好的说明拼接 T恤,看到相当不错的从Linus本人解释。他指出,如何使用拼接基本上就像环以上,使用,除了缓冲器是在内核,所以数据不必在内核和用户空间之间传送,或者可能甚至不永远穿过的CPU(称为零拷贝我/ O)。

In Linux 2.6.17, the splice system call was introduced, and as of 2.6.23 is used internally to implement sendfile. splice is a more general purpose API than sendfile. For a good description of splice and tee, see the rather good explanation from Linus himself. He points out how using splice is basically just like the loop above, using read and write, except that the buffer is in the kernel, so the data doesn't have to transferred between the kernel and user space, or may not even ever pass through the CPU (known as "zero-copy I/O").

这篇关于发送和C接收套接字编程文件中的Linux / C ++(GCC / G ++)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆