当前位置: 动力学知识库 > 问答 > 编程问答 >

c++ - socket() and sendto() dont return error codes when theres no internet connection

问题描述:

Why does socket() not return INVALID_SOCKET when I have no internet connection? I thought it would fail and then I could exit my function. My function's error checking continues till recvfrom() and then just hangs when I have no internet connection. I thought that socket() or sendto() would return an error code when I have no internet connection but they are not. I am trying to rely on their failure as a sign the user has no internet connection and exit my function but thats just not working for some weird reason.

void myFunc()

{

WSADATA wsaData;

WSAStartup(MAKEWORD(2, 2), &wsaData);

struct sockaddr_in server_addr;

memset(&server_addr, 0, sizeof(server_addr));

server_addr.sin_family = AF_INET;

server_addr.sin_addr.s_addr = inet_addr("myipaddress");

server_addr.sin_port = htons(123);

// Doesn't fail when there's no internet connection

protoent *proto = getprotobyname("udp");

int s = socket(PF_INET, SOCK_DGRAM, proto->p_proto);

if (s == INVALID_SOCKET) {

goto Cleanup;

}

// Doesn't fail when there's no internet connection

char msg[48] = { 0x08, 0, 0, 0, 0, 0, 0, 0, 0 };

int iResult = sendto(s, msg, sizeof(msg), 0, (struct sockaddr *) &server_addr, sizeof(server_addr));

if (iResult == SOCKET_ERROR) {

goto Cleanup;

}

// Hangs when there's no internet connection

memset(msg, 0, sizeof(msg));

struct sockaddr saddr;

socklen_t saddr_l = sizeof(saddr);

iResult = recvfrom(s, msg, 48, 0, &saddr, &saddr_l);

if (iResult == SOCKET_ERROR) {

goto Cleanup;

}

Cleanup:

closesocket(s);

WSACleanup();

}

网友答案:

Because there is no requirement for sockets to be connected to the internet. Many applications use sockets for inter-process communication on a single machine. Such applications can still run fine when there is no internet connection.

sendto() could arguably return an error code; it can (under certain situations, as demonstrated by the desktop notification about network connection status) know that the packet can never be delivered. However, UDP communication and sendto() make no guarantees about delivery whatsoever, and apparently the implementation you are using does not consider the lack of connection worthy of an error code. Arguably this is a quality of implementation issue.

recvfrom() simply waits as long as you have specified (possibly indefinitely) for a message, but never receives one. Again, this is within spec, and again it could be considered a quality of implementation issue whether or not this particular situation is flagged or not.

网友答案:

I looked into the linux man page for sendto (assuming that all relevant the implementations are sufficiently similar to the berkley sockets baseline) here:

http://linux.die.net/man/2/sendto

The documentation does not mention reporting and error if the network stack 'knows' that the message is undeliverable. This is reasonable, since the socket's transport may well not be IP4 or IP6. It could be any transport we chose to write a driver for: packet radio, serial cables or carrier-pigeons (if we could figure out the hardware for loading the printed messages into their satchels).

The only reference to possible errors from the transport is here:

These are some standard errors generated by the socket layer. Additional errors may be generated and returned from the underlying protocol modules; see their respective manual pages.

As mentioned by others, UDP is an unreliable datagram protocol. Unreliability is expected. Non-delivery of a message is expected. Therefore not really an error. There would be little incentive for a protocol-layer author to code for handling transport errors - since they too are expected and not an error in the context of this protocol.

When a socket is opened over TCP, then lack of socket continuity is an error. If the transport reports that packet delivery is not possible (for a sufficiently long time) then this is an error condition in the protocol.

分享给朋友:
您可能感兴趣的文章:
随机阅读: