9

基本的にファイルを転送して、ソケットにデータを送信する必要があります。

send()関数のドキュメントによると、次のように述べています。

If no error occurs, send returns the total number of bytes sent, which can be less than the number requested to be sent in the len parameter. Otherwise, a value of SOCKET_ERROR is returned,

私が心配しているのは、戻り値が要求された値よりも小さい可能性があるということです。ファイルからの読み取りとソケットへの書き込みを行っているため、すべてのバイトが送信されない可能性があるため、バッファ全体が送信されなかった場合は再試行する必要があると思いますか?その場合、私はどういうわけか同じバッファ上のポインタを読み取ったバイト数だけ進めて、それを再送信する必要があると思いますか?

それがその方法かどうか知りたいだけですか?または、すべてのデータが送信されなかったときに心配することなく、要求されたすべてのデータが送信されるようにするための非常に賢い方法がありますか?

ありがとう、

4

3 に答える 3

11

はい、バッファポインタを進めて、バッファsend全体が消費されるか、ハードエラーが発生するまで呼び出しを繰り返す必要があります。標準のイディオムは次のようになります。

int
send_all(int socket, const void *buffer, size_t length, int flags)
{
    ssize_t n;
    const char *p = buffer;
    while (length > 0)
    {
        n = send(socket, p, length, flags);
        if (n <= 0)
            return -1;
        p += n;
        length -= n;
    }
    return 0;
}

境界が重要なデータグラム(UDPなど)を送信する場合は、この手法を使用できないことに注意してください。ショートセンドを失敗として扱う必要があります。

于 2013-01-06T16:36:29.050 に答える
6

次のようなことを試すことができます:

int ret, bytes = 0;
while (bytes < buflen) {
    ret = send(sock_fd, buf+bytes, buflen-bytes, flags);
    //check for errors
    if (ret == -1) {
        // handle error
    }
    bytes+=ret;
}
于 2013-01-06T16:36:44.227 に答える
3

sendはい、 (など)によって返される値について心配する必要はありませんwrite。それを回避する非常に賢い方法はありませんが、優れたリチャード・スティーブンスによって書かれたいくつかの関数、すなわちreadnとがありwritenます。

informationitに関するこの記事には、これらの関数のバージョンがあるようです。

于 2013-01-06T16:34:17.443 に答える