By default, the socket is in blocking mode. If you switch it to non-blocking mode using ioctlsocket(FIONBIO)
, you can use select()
to control timeouts:
SOCKET sock, connected; int bytes_recieved; char send_data [128] , recv_data[128]; SOCKADDR_IN server_addr,client_addr; int sin_size; int j = 0, ret; fd_set fd; timeval tv; sock = ::socket(AF_INET, SOCK_STREAM, 0); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(4000); server_addr.sin_addr.s_addr = INADDR_ANY; ::bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); ::listen(sock, 1); ::fflush(stdout); u_long nbio = 1; ::ioctlsocket(sock, FIONBIO, &nbio); while(1) { FD_ZERO(&fd); FD_SET(sock, &fd); tv.tv_sec = 5; tv.tv_usec = 0; if (select(0, &fd, NULL, NULL, &tv) > 0) { sin_size = sizeof(struct sockaddr_in); connected = ::accept(sock, (struct sockaddr *)&client_addr, &sin_size); nbio = 1; ::ioctlsocket(connected, FIONBIO, &nbio); while (1) { j++; if (::send(connected, send_data, strlen(send_data), 0) < 0) { //dealing with lost communication ? //and reastablishing communication //set timeout and reset on timeout error if (WSAGetLastError() == WSAEWOULDBLOCK) { FD_ZERO(&fd); FD_SET(connected, &fd); tv.tv_sec = 5; tv.tv_usec = 0; if (select(0, NULL, &fd, NULL, &tv) > 0) continue; } break; } } closesocket(connected); } }
source share