Non-blocking TCP socket and flushing right after send?

回眸只為那壹抹淺笑 提交于 2019-12-24 01:55:20

问题


I am using Windows socket for my application(winsock2.h). Since the blocking socket doesn't let me control connection timeout, I am using non-blocking one. Right after send command I am using shutdown command to flush(I have to). My timeout is 50ms and the thing I want to know is if the data to be sent is so big, is there a risk of sending only a portion of data or sending nothing at all? Thanks in advance...

    hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    u_long iMode=1;
    ioctlsocket(hSocket,FIONBIO,&iMode);
    connect(hSocket, (sockaddr*)(&sockAddr),sockAddrSize);
    send(hSocket, sendbuf, sendlen, 0);
    shutdown(hSocket, SD_BOTH);
    Sleep(50);
    closesocket(hSocket);

回答1:


Non-blocking TCP socket and flushing right after send?

There is no such thing as flushing a TCP socket.

Since the blocking socket doesn't let me control connection timeout

False. You can use select() on a blocking socket.

I am using non-blocking one.

Non sequitur.

Right after send command I am using shutdown command to flush(I have to).

You don't have to, and shutdown() doesn't flush anything.

My timeout is 50ms

Why? The time to send data depends on the size of the data. Obviously. It does not make any sense whatsoever to use a fixed timeout for a send.

and the thing I want to know is if the data to be sent is so big, is there a risk of sending only a portion of data or sending nothing at all?

In blocking mode, all the data you provided to send() will be sent if possible. In non-blocking mode, the amount of data represented by the return value of send() will be sent, if possible. In either case the connection will be reset if the send fails. Whatever timeout mechanism you superimpose can't possibly change any of that: specifically, closing the socket asynchronously after a timeout will only cause the close to be appended to the data being sent. It will not cause the send to be aborted.

Your code wouldn't pass any code review known to man. There is zero error checking; the sleep is completely pointless; and shutdown before close is redundant. If the sleep is intended to implement a timeout, it doesn't.

I want to be sending data as fast as possible.

You can't. TCP implements flow control. There is exactly nothing you can do about that. You are rate-limited by the receiver.

Also the 2 possible cases are: server waits too long to accept connection

There is no such case. The client can complete a connection before the server ever calls accept(). If you're trying to implement a connect timeout shorter than the default of about a minute, use select().

or receive.

Nothing you can do about that: see above.

So both connecting and writing should be done in max of 50ms since the time is very important in my situation.

See above. It doesn't make sense to implement a fixed timeout for operations that take variable time. And 50ms is far too short for a connect timeout. If that's a real issue you should keep the connection open so that the connect delay only happens once: in fact you should keep TCP connections open as long as possible anyway.

I have to flush both write and read streams

You can't. There is no operation in TCP that will flush either a read stream or a write stream.

because the server keeps sending me unnecessarly big data and I have limited internet connection.

Another non sequitur. If the server sends you data, you have to read it, otherwise you will stall the server, and that doesn't have anything to do with flushing your own write stream.

Actually I don't even want a single byte from the server

Bad luck. You have to read it. [If you were on BSD Unix you could shutdown the socket for input, which would cause data from the server to be thrown away, but that doesn't work on Windows: it causes the server to get a connection reset.]




回答2:


Thanks to EJP and Martin, now I have created a second thread to check. Also in the code I posted in my question, I added "counter=0;" line after the "send" line and removed shutdown. It works just as I wanted now. It never waits more than 50ms :) Really big thanks

unsigned __stdcall SecondThreadFunc( void* pArguments )

{

while(1)
{
    counter++;
    if (counter > 49)
    {
        closesocket(hSocket);
        counter = 0;
        printf("\rtimeout");
    }

    Sleep(1);
}
return 0;

}



来源:https://stackoverflow.com/questions/11491147/non-blocking-tcp-socket-and-flushing-right-after-send

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!