UDP WSARecvMsg return WSAEWOULDBLOCK but Wireshark catch packets - sockets

I have a problem while reading data from UDP socket (port 7078). I've called WSARecvMsg function and received WSAEWOULDBLOCK error. But, Wireshark catch incoming UDP packet on port 7078! Please help me!
This is my code for creating and binding socket
static ortp_socket_t create_and_bind(const char *addr, int *port, int *sock_family, bool_t reuse_addr){
int err;
int optval = 1;
ortp_socket_t sock=-1;
char num[8];
struct addrinfo hints, *res0, *res;
if (*port==-1) *port=0;
if (*port==0) reuse_addr=FALSE;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
snprintf(num, sizeof(num), "%d",*port);
err = getaddrinfo(addr,num, &hints, &res0);
if (err!=0) {
ortp_warning ("Error in getaddrinfo on (addr=%s port=%i): %s", addr, *port, gai_strerror(err));
return -1;
}
for (res = res0; res; res = res->ai_next) {
sock = socket(res->ai_family, res->ai_socktype, 0);
if (sock==-1)
continue;
if (reuse_addr){
err = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
(SOCKET_OPTION_VALUE)&optval, sizeof (optval));
if (err < 0)
{
ortp_warning ("Fail to set rtp address reusable: %s.", getSocketError());
}
}
err = 0;
switch (res->ai_family) {
default:
case AF_INET:
break;
case AF_INET6:
break;
}
if (err < 0) {
ortp_warning("Fail to set recv TTL/HL socket option: %s.", getSocketError());
}
*sock_family=res->ai_family;
err = bind (sock, res->ai_addr, res->ai_addrlen);
if (err != 0){
ortp_debug ("Fail to bind rtp socket to (addr=%s port=%i) : %s.", addr, *port, getSocketError());
close_socket (sock);
sock=-1;
continue;
}
switch (res->ai_family)
{
case AF_INET:
if (IN_MULTICAST(ntohl(((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr)))
{
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr;
mreq.imr_interface.s_addr = INADDR_ANY;
err = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (SOCKET_OPTION_VALUE) &mreq, sizeof(mreq));
if (err < 0){
ortp_warning ("Fail to join address group: %s.", getSocketError());
close_socket (sock);
sock=-1;
continue;
}
}
break;
case AF_INET6:
if (IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr)))
{
struct ipv6_mreq mreq;
mreq.ipv6mr_multiaddr = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
mreq.ipv6mr_interface = 0;
err = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (SOCKET_OPTION_VALUE)&mreq, sizeof(mreq));
if (err < 0)
{
ortp_warning ("Fail to join address group: %s.", getSocketError());
close_socket (sock);
sock=-1;
continue;
}
}
break;
}
break;
}
freeaddrinfo(res0);
#if defined(WIN32) || defined(_WIN32_WCE)
if (ortp_WSARecvMsg == NULL) {
GUID guid = WSAID_WSARECVMSG;
DWORD bytes_returned;
if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
&ortp_WSARecvMsg, sizeof(ortp_WSARecvMsg), &bytes_returned, NULL, NULL) == SOCKET_ERROR) {
ortp_warning("WSARecvMsg function not found.");
}
}
#endif
if (sock!=-1){
set_non_blocking_socket (sock);
if (*port==0){
struct sockaddr_storage saddr;
socklen_t slen=sizeof(saddr);
err=getsockname(sock,(struct sockaddr*)&saddr,&slen);
if (err==-1){
ortp_error("getsockname(): %s",getSocketError());
close(sock);
return (ortp_socket_t)-1;
}
err=getnameinfo((struct sockaddr*)&saddr, slen, NULL, 0, num, sizeof(num), NI_NUMERICHOST | NI_NUMERICSERV);
if (err!=0){
ortp_error("getnameinfo(): %s",gai_strerror(err));
close(sock);
return (ortp_socket_t)-1;
}
*port=atoi(num);
}
}
return sock;
}
And I use WSAIoctl to get WSARECVMSG function pointer
typedef INT (WINAPI * LPFN_WSARECVMSG)(SOCKET, LPWSAMSG, LPDWORD, LPWSAOVERLAPPED, LPWSAOVERLAPPED_COMPLETION_ROUTINE);
static LPFN_WSARECVMSG ortp_WSARecvMsg = NULL;
if (ortp_WSARecvMsg == NULL) {
GUID guid = WSAID_WSARECVMSG;
DWORD bytes_returned;
if (WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
&ortp_WSARecvMsg, sizeof(ortp_WSARecvMsg), &bytes_returned, NULL, NULL) == SOCKET_ERROR) {
ortp_warning("WSARecvMsg function not found.");
}
}
My code for receiving data
int rtp_session_rtp_recv_abstract(ortp_socket_t socket, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen) {
int ret;
int bufsz = (int) (msg->b_datap->db_lim - msg->b_datap->db_base);
char control[512];
WSAMSG msghdr;
WSACMSGHDR *cmsghdr;
WSABUF data_buf;
DWORD bytes_received;
if (ortp_WSARecvMsg == NULL) {
return recvfrom(socket, (char *)msg->b_wptr, bufsz, flags, from, fromlen);
}
memset(&msghdr, 0, sizeof(msghdr));
memset(control, 0, sizeof(control));
if(from != NULL && fromlen != NULL) {
msghdr.name = from;
msghdr.namelen = *fromlen;
}
data_buf.buf = (char *)msg->b_wptr;
data_buf.len = bufsz;
msghdr.lpBuffers = &data_buf;
msghdr.dwBufferCount = 1;
msghdr.Control.buf = control;
msghdr.Control.len = sizeof(control);
msghdr.dwFlags = flags;
ret = ortp_WSARecvMsg(socket, &msghdr, &bytes_received, NULL, NULL);
if(fromlen != NULL)
*fromlen = msghdr.namelen;
if(ret >= 0) {
ret = bytes_received;
}
else
{
int i;
long m_ErrorCode = WSAGetLastError();
i = 0;
}
return ret;
}

Related

recvfrom() socket is not working after this function

I am facing issue with calling to recvfrom function:
recvfrom(sock, dat, sizeof(dat), 0, (void *)&peername, &peernamelen);
Until this all functions are working.
Please let me know where I am making mistake. Should I use bind or not, or any mistake from this.
Output:
before sockname
after sockname
after sock
after setsockopt
after Bind
before recvfrom
My code:
struct sockaddr_can sockname = {
.can_family = AF_CAN,
.can_addr.j1939 = {
.addr = J1939_NO_ADDR,
.name = J1939_NO_NAME,
.pgn = J1939_NO_PGN,
},
}, peername = {
.can_family = AF_CAN,
.can_addr.j1939 = {
.addr = J1939_NO_ADDR,
.name = J1939_NO_NAME,
.pgn = J1939_NO_PGN,
},
};
uint8_t dat[128];
int valid_peername = 0;
unsigned int todo_send = 0;
int todo_recv = 0, todo_echo = 0, todo_prio = -1;
int todo_connect = 0, todo_names = 0, todo_wait = 0, todo_rebind = 0;
int todo_broadcast = 0, todo_promisc = 0;
int no_bind = 0,i;
printf("before sockname\n");
sockname.can_ifindex = if_nametoindex(CAN_SOCKET_NAME);
printf("after sockname\n");
sock = socket(PF_CAN, SOCK_DGRAM, CAN_J1939);
printf("after sock\n");
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &todo_broadcast, sizeof(todo_broadcast));
printf("after setsockopt\n");
ret = bind(sock, (void *)&sockname, sizeof(sockname));
if (ret < 0)
err(1, "bind()");
printf("after Bind\n");
while(1){
peernamelen = sizeof(peername);
printf("before recvfrom\n");
recvfrom(sock, dat, sizeof(dat), 0, (void *)&peername, &peernamelen);
printf("%02x %05x:", peername.can_addr.j1939.addr, peername.can_addr.j1939.pgn);
for (i = 0, j = 0; i < ret; ++i, j++) {
if (j == 8) {
printf("\n%05x ", i);
j = 0;
}
printf(" %02x", dat[i]);
}
printf("\n");
}
Please help me to solve this issue.

failure on updating socket map

I'm doing BPF programming and I want to add a socket to socket map. The code is as follows
When it detects a listen/connect, the socket is added to a socket map
__section("sockops")
int bpf_sockmap(struct bpf_sock_ops *skops)
{
switch (skops->op) {
case BPF_SOCK_OPS_TCP_LISTEN_CB:
if (skops->family == 2) {
bpf_sock_ops_ipv4(skops);
}
break;
case BPF_SOCK_OPS_TCP_CONNECT_CB:
if (skops->family == 2) {
bpf_sock_ops_ipv4(skops);
}
break;
default:
break;
}
return 0;
}
The bpf_sock_ops_ipv4() is
void bpf_sock_ops_ipv4(struct bpf_sock_ops *skops)
{
struct sock_key key = {};
int ret;
extract_key4_from_ops(skops, &key); // extract some field from skops to form the key structure
ret = sock_hash_update(skops, &sock_ops_map, &key, BPF_ANY);
if (ret != 0) {
printk("sock_hash_update() failed, ret: %d\n", ret);
}
printk("sockmap: op %d, port %d --> %d\n",
skops->op, skops->local_port, bpf_ntohl(skops->remote_port));
}
The map structure
struct bpf_map_def __section("maps") sock_ops_map = {
.type = BPF_MAP_TYPE_SOCKHASH,
.key_size = sizeof(struct sock_key),
.value_size = sizeof(int),
.max_entries = 65535,
.map_flags = 0,
};
The key structure
struct sock_key {
__u32 ops;
__u32 sip4;
__u32 dip4;
__u8 family;
__u8 pad1;
__u16 pad2;
__u32 pad3;
__u32 sport;
__u32 dport;
} __attribute__((packed));
When I load it and init a server using sudo socat TCP4-LISTEN:1001,fork exec:cat, The update fails
sudo cat /sys/kernel/debug/tracing/trace_pipe
socat-1239 [002] .... 2020.217663: 0: sock_hash_update() failed, ret: -95
socat-1239 [002] .... 2020.217682: 0: sockmap: op 11, port 1001 --> 0

recv function in socket programming fails when I am using MSG_WAITALL flag

I have written a very simple code for client side of a socket.
this is my receive function:
int n32RecvLength = 10;
do {
n32RecvLength = recv(m_socketConnectSocket, m_szRecvBuffer, m_n32BufferLength, MSG_WAITALL);
if ( n32RecvLength > 0 )
{
printf("\nBytes received: %d\n", n32RecvLength);
//for(int i = 0; i< n32RecvLength; i++)
//putchar(m_szRecvBuffer[i]);
if (evRecPacket != NULL)
{
evRecPacket(static_cast<void*>(m_ptrvDerivedClass),reinterpret_cast<unsigned char*>(m_szRecvBuffer) , n32RecvLength);
}
}
else if ( n32RecvLength == 0 )
{
printf("Connection closed!!!!!!!\n");
if(evDisconnected != NULL)
evDisconnected(static_cast<void*>(m_ptrvDerivedClass));
break;
}
else
{
int errorNum = WSAGetLastError();
if (errorNum == WSAETIMEDOUT)
{
printf ("\n timeOut\n");
n32RecvLength = 1;
}
else
{
printf("recv failed with error: %d\n", errorNum);
if(evDisconnected != NULL)
evDisconnected(static_cast<void*>(m_ptrvDerivedClass));
break;
}
}
} while( n32RecvLength > 0 );
and I have initialized it in this function:
WSADATA swsaData;
struct addrinfo *result = NULL;
struct addrinfo hints;
unsigned int n32CheckCondition = 0;
n32CheckCondition = WSAStartup(MAKEWORD(2,2), &swsaData);
if (n32CheckCondition != 0) {
printf("WSAStartup failed with error: %d\n", n32CheckCondition);
return;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
char szPortNumber[100];
itoa(m_n32PortNumber,szPortNumber , 10);
n32CheckCondition = getaddrinfo(m_szIpServerAddr, szPortNumber, &hints, & m_ptrsResult);
if ( n32CheckCondition != 0 ) {
printf("getaddrinfo failed with error: %d\n", n32CheckCondition);
WSACleanup();
return;
}
m_socketConnectSocket = socket( m_ptrsResult->ai_family, m_ptrsResult->ai_socktype, m_ptrsResult->ai_protocol);
if (m_socketConnectSocket == INVALID_SOCKET)
{
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return;
}
// to set timeout feature to your system, uncomment the two following lines and adjust it
DWORD timeout = 10000; // mili second!
setsockopt(m_socketConnectSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
I am using recv function with MSG_WAITALL flag. I have set the timeout = 10000 milliseconds.
I have set the m_n32BufferLength = 8. when I send a 8-byte data, it works fine, but when I send 9 byte it shows first 8 bytes and after a few second (timeout value) the recv(...) returns zero. I know when recv returns zero, it means that socket has been closed. but I have not closed the socket. and I also loss the 9th byte of my data.
could you please tell me what I should do?

IOCP not getting triggered

I have writen an IOCP program and I am testing it through VPN.
It was all working OK, but then the server disconnected and the client GetQueuedCompletionStatus didn't trigger an exception.
I waited for one day,cbut it didn't get better. When I changed to a new VPN, the problem was solved, and I didn't get that problem later.
What's wrong? Has anybody seen the same problem before?
enter code here
enter code here
#include "XYTransport.h"
//---------------------------------------------------------------------------
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
//---------------------------------------------------------------------------
#define XYTCP_LIST_CLIENT0 0
#define XYTCP_LIST_CLIENT1 1
//---------------------------------------------------------------------------
#define XYTRANSPORT_TYPE_TCP_OPEN 0
#define XYTRANSPORT_TYPE_TCP_RECV 1
#define XYTRANSPORT_TYPE_TCP_SEND 2
//---------------------------------------------------------------------------
typedef struct tagXYOVERLAPPED
{
OVERLAPPED o;
SOCKET s;
UINT flags;
WSABUF wb;
}XYOVERLAPPED, *PXYOVERLAPPED;
//---------------------------------------------------------------------------
inline LPVOID XYAlloc(HANDLE heap, UINT size)
{
return(HeapAlloc(heap, 0, size));
}
inline VOID XYFree(HANDLE heap, LPVOID lpdata)
{
HeapFree(heap, 0, lpdata);
}
inline PXYOVERLAPPED XYOverlappedPop(PXYTRANSPORT pt, LPBYTE buffer, SOCKET s)
{
PXYOVERLAPPED pto = NULL;
SOCKADDR_IN name;
if (buffer == NULL)
{
buffer = (LPBYTE)VirtualAlloc(NULL, pt->bufferlength, MEM_COMMIT, PAGE_READWRITE);
}
if (buffer != NULL)
{
pto = (PXYOVERLAPPED)MALLOC(sizeof(XYOVERLAPPED));
if (pto != NULL)
{
pto->wb.buf = (char *)buffer;
pto->wb.len = pt->bufferlength;
if (s == INVALID_SOCKET)
{
pto->s = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
if (pto->s != INVALID_SOCKET)
{
ZeroMemory(&name, sizeof(name));
name.sin_family = AF_INET;
name.sin_addr.S_un.S_addr = INADDR_ANY;
//name.sin_port = fn_htons(0);
name.sin_port = 0;
if (bind(pto->s, (const SOCKADDR *)&name, sizeof(name)) == 0)
{
if (CreateIoCompletionPort((HANDLE)pto->s, pt->hcompletion, (ULONG_PTR)pto->s, 0) == pt->hcompletion)
{
//
}
}
}
}
else
{
pto->s = s;
}
}
}
return(pto);
}
BOOL XYTCPPushReceive(PXYTRANSPORT pt, PXYOVERLAPPED pto, SOCKET s)
{
DWORD numberofbytes;
DWORD flags = 0;
BOOL result;
int error;
if (pto == NULL)
{
pto = XYOverlappedPop(pt, NULL, s);
}
ZeroMemory(&pto->o, sizeof(OVERLAPPED));
pto->flags = XYTRANSPORT_TYPE_TCP_RECV;
result = WSARecv(pto->s, &pto->wb, 1, &numberofbytes, &flags, &pto->o, NULL) != SOCKET_ERROR;
if (!result)
{
error = WSAGetLastError();
result = error == WSA_IO_PENDING;
if (!result)
{
printf("WSARecv\n");
}
}
return(result);
}
inline BOOL XYTCPPushSend(PXYTRANSPORT pt, PXYOVERLAPPED pto)
{
DWORD numberofbytes;
ULONG flags = MSG_PARTIAL;
BOOL result;
int error;
ZeroMemory(&pto->o, sizeof(OVERLAPPED));
pto->flags = XYTRANSPORT_TYPE_TCP_SEND;
//
pto->wb.len = 1024;
//
result = WSASend(pto->s, &pto->wb, 1, &numberofbytes, flags, &pto->o, NULL) != SOCKET_ERROR;
if (!result)
{
error = WSAGetLastError();
result = error == WSA_IO_PENDING;
if (!result)
{
printf("Send Error\n");
}
}
return(result);
}
DWORD WINAPI XYTransportWorkProc(LPVOID parameter)
{
PXYTRANSPORT pt = (PXYTRANSPORT)parameter;
HANDLE hcompletion = pt->hcompletion;
LPOVERLAPPED po;
PXYOVERLAPPED pto;
ULONG_PTR completionkey;
DWORD numberofbytes;
SOCKET s;
BOOL flag;
UINT type;
UINT count;
UINT error;
while(pt->working)
{
flag = GetQueuedCompletionStatus(hcompletion, &numberofbytes, &completionkey, &po, INFINITE);
if (po != NULL)
{
pto = (PXYOVERLAPPED)CONTAINING_RECORD(po, XYOVERLAPPED, o);
s = (SOCKET)completionkey;
type = pto->flags;
if (!flag)
{
//OutputDebugValue(_T("Except Error"), type, numberofbytes);
printf("Except Error %d\n", type);
}
if (numberofbytes == 0)
{
//OutputDebugValue(_T("Length Error"), type);
printf("Length Error %d\n", type);
}
if (!flag)
{
numberofbytes = 0;
}
switch (type)
{
case XYTRANSPORT_TYPE_TCP_OPEN:
if (flag)
{
setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
XYTCPPushSend(pt, pto);
printf("connected\n");
if (!XYTCPPushReceive(pt, NULL, s))
{
//
}
else
{
printf("post recv\n");
}
break;
}
break;
case XYTRANSPORT_TYPE_TCP_RECV:
if (numberofbytes > 0)
{
XYTCPPushReceive(pt, pto, s);
//OutputDebugString(_T("Recv"));
printf("Recv %d\n", numberofbytes);
}
else
{
printf("Recv Error\n");
}
break;
case XYTRANSPORT_TYPE_TCP_SEND:
if (numberofbytes > 0)
{
XYTCPPushSend(pt, pto);
printf("Send %d\n", numberofbytes);
}
else
{
printf("Send Except\n");
}
break;
default:
break;
}
}
else
{
printf("Quit %d, %d", GetCurrentThreadId(), flag);
break;
}
}
return(0);
}
VOID XYTransportStartup(PXYTRANSPORT pt, UINT pagesize)
{
pt->hcompletion = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (pt->hcompletion != INVALID_HANDLE_VALUE)
{
pt->lpfnConnectEx = NULL;
pt->bufferlength = pagesize;
pt->working = TRUE;
pt->hthread = CreateThread(NULL, 0, XYTransportWorkProc, (LPVOID)pt, 0, NULL);
}
}
BOOL XYTCPConnect(PXYTRANSPORT pt, const CHAR *host, USHORT port)
{
GUID id = WSAID_CONNECTEX;
DWORD numberofbytes = 0;
PXYOVERLAPPED pto;
SOCKADDR_IN name;
BOOL result = FALSE;
int error;
pto = XYOverlappedPop(pt, NULL, INVALID_SOCKET);
if (pt->lpfnConnectEx != NULL || WSAIoctl(pto->s, SIO_GET_EXTENSION_FUNCTION_POINTER, &id, sizeof(id), &pt->lpfnConnectEx, sizeof(pt->lpfnConnectEx), &numberofbytes, NULL, NULL) != SOCKET_ERROR)
{
ZeroMemory(&pto->o, sizeof(OVERLAPPED));
pto->flags = XYTRANSPORT_TYPE_TCP_OPEN;
ZeroMemory(&name, sizeof(name));
name.sin_family = AF_INET;
name.sin_port = htons(port);
name.sin_addr.S_un.S_addr = inet_addr(host);
if (name.sin_addr.S_un.S_addr != INADDR_NONE)
{
numberofbytes = 0;
result = pt->lpfnConnectEx(pto->s, (SOCKADDR *)&name, sizeof(name), NULL, 0, &numberofbytes, &pto->o);
if(!result)
{
error = WSAGetLastError();
result = error == ERROR_IO_PENDING;
if (!result)
{
printf("ConnectEx error\n");
}
}
}
}
return(result);
}
//---------------------------------------------------------------------------
the client Thrown an exception is what i desired,so i can know.
I am using C language to write. Under normal circumstances, disconnect one end and the other end will trigger an exception, but I have found that sometimes have to wait a very long time, at least I'm waiting for more than one day are not triggered, and sometimes even in the off time can continue to deliver WSASend success for some time.

WSAWaitForMultipleEvents returns timeout when send() is successful

I am working on a application which involves socket programming. I am trying to implement reset functionality in this application in case server is closed or crashed for any reason. For reset I need to reestablish communication between the client and server after manual restart of server. Now I am able to send request from client to server which server would process and send reply to client. Send() function at server side is returning with success but WSAWaitForMultipleEvents() function at client side is returning with WSA_TIME_OUT every time.
I restart my socket at client side with SO_REUSEADDR true value on reset. I am very new to network programming i am not able to understand why this is happening.
here is my code at client side. Its little messed up so please bear with me
void
SocketListner::run()
{
// std::cout << "Thread ID of SocketListener : " << QThread::currentThreadId() << "\n";
if(_isFrameGrabber)
{
_listenForFrames();
}
else
{
_listenForRequests();
}
}
void
SocketListner::_listenForRequests()
{
DWORD eventVal;
unsigned int eventSock;
WSANETWORKEVENTS networkEvents;
std::stringstream ss;
int bufferLength = 500;
char * msg = new char[bufferLength];
std::string Msg = "";
int retCode;
int diff;
while(!_done)
{
// Giving it one second less than the condition wait time
// OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_destructorMutex);
if((eventVal=WSAWaitForMultipleEvents(_eventCnt, _socketEvents, false, 3000, false)) == WSA_WAIT_FAILED)
{
ss.str("");
ss << "WSAWaitForMultipleEvents() failed with error : " << WSAGetLastError();
LOG_ERROR(ss.str());
emit socketErrorSignal(eventVal);
break;
}
else if(eventVal == WSA_WAIT_TIMEOUT)
{
//OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if(_done)
{
WSACloseEvent(_socketEvents[0]);
if(_eventCnt==2)
WSACloseEvent(_socketEvents[1]);
break;
}
continue;
}
if( (diff=(eventVal - WSA_WAIT_EVENT_0)) == 0 )
eventSock = s_sock;
else if(diff == 1)
eventSock = c_sock;
else
continue;
if((WSAEnumNetworkEvents(eventSock, _socketEvents[eventVal - WSA_WAIT_EVENT_0], &networkEvents)) == SOCKET_ERROR)
{
ss.str("");
ss << "WSAEnumNetworkEvents() failed with error : " << WSAGetLastError();
LOG_ERROR(ss.str());
// break;
}
if (networkEvents.lNetworkEvents & FD_ACCEPT)
{
if (networkEvents.iErrorCode[FD_ACCEPT_BIT] != 0)
{
ss.str("");
ss << "FD_ACCEPT failed with error : " << networkEvents.iErrorCode[FD_ACCEPT_BIT];
LOG_ERROR(ss.str());
break;
}
if ((c_sock = accept(eventSock, NULL, NULL)) == INVALID_SOCKET)
{
ss.str("");
ss << "accept() failed with error : " << WSAGetLastError();
LOG_ERROR(ss.str());
break;
}
if ((_socketEvents[_eventCnt] = WSACreateEvent()) == WSA_INVALID_EVENT)
{
std::stringstream ss;
ss << "WSACreateEvent() failed with error : " << WSAGetLastError();
LOG_ERROR(ss.str());
break;
}
if( WSAEventSelect(c_sock, _socketEvents[_eventCnt], FD_READ | FD_CLOSE) == SOCKET_ERROR)
{
ss.str("");
ss << "WSAEventSelect() failed with error : " << WSAGetLastError();
LOG_ERROR(ss.str());
break;
}
++_eventCnt;
}
if(networkEvents.lNetworkEvents & FD_READ)
{
if (networkEvents.lNetworkEvents & FD_READ && networkEvents.iErrorCode[FD_READ_BIT] != 0)
{
ss.str("");
ss << "FD_READ failed with error : " << networkEvents.iErrorCode[FD_READ_BIT];
LOG_ERROR(ss.str());
}
if((retCode = recv(eventSock, msg, bufferLength, 0)) > 0)
{
int place = 0;
while(place < retCode)
{
if(msg[place] == '\n' && Msg.length() != 0)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
//Naresh: Replacing std::vector by std::queue
_requests.push(Msg);
Msg = "";
}
else
{
if(msg[place] != '\0')
Msg.push_back(msg[place]);
}
++place;
}
}
//Abhishek: Testing Complete else block
else if(retCode == 0 || WSAGetLastError() == WSAECONNRESET)
{
//Abhishek
shutdown(c_sock, SD_BOTH);
shutdown(s_sock, SD_BOTH);
closesocket(c_sock);
closesocket(s_sock);
int error = WSAGetLastError();
if(!_initialize())
{
_done = true;
return;
}
}
else if(retCode == SOCKET_ERROR)
{
bool stopListening=false;
int errorCode = WSAGetLastError();
_processSocketError(errorCode, stopListening);
if(stopListening)
{
LOG_WARNING("Connection with the partner lost.");
emit socketErrorSignal(errorCode);
break;
}
}
}
if(networkEvents.lNetworkEvents & FD_CLOSE)
{
if (networkEvents.iErrorCode[FD_CLOSE_BIT] != 0)
{
ss.str("");
ss << "FD_CLOSE failed with error : " << networkEvents.iErrorCode[FD_CLOSE_BIT];
LOG_ERROR(ss.str());
emit socketErrorSignal(networkEvents.iErrorCode[FD_CLOSE_BIT]);
}
else if(!_stopped)
{
LOG_ERROR("Lost Connection with Wall.");
emit socketErrorSignal(networkEvents.iErrorCode[FD_CLOSE_BIT]);
}
closesocket(eventSock);
break;
}
//Sleep(100);
} //While
delete[] msg;
msg = NULL;
// If any failure occurs make the _bDone variable to true, as thread is no longer running
_cleanUpCondition.signal();
}
here is _initialize function
bool
SocketListner::_initialize()
{
if(_IP.length() <= 0)
{
LOG_ERROR("Host IP Address : " + _IP + " is invalid.");
return false;
}
//Naresh: replacing vector by queue
while(!_requests.empty())
{
_requests.pop();
}
WSADATA wsaData;
if(WSAStartup(0x101,&wsaData) != 0)
{
LOG_ERROR("Failed WSAStartUp() call.");
return false;
}
sockaddr_in SockAddr;
SockAddr.sin_family = AF_INET;
SockAddr.sin_port = htons(_port);
SockAddr.sin_addr.s_addr = inet_addr(_IP.c_str());
s_sock = socket(AF_INET,SOCK_STREAM,0);
//Abhishek:BugFix for reset enable address reuse else bind() will fail
bool addrReuse = true;
setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, (const char*) &addrReuse, sizeof(BOOL));
if(!_isFrameGrabber)
{
if ((_socketEvents[_eventCnt] = WSACreateEvent()) == WSA_INVALID_EVENT)
{
std::stringstream ss;
ss << "WSACreateEvent() failed with error : " << WSAGetLastError();
LOG_ERROR(ss.str());
return false;
}
if(WSAEventSelect(s_sock, _socketEvents[_eventCnt], FD_ACCEPT | FD_CLOSE)== SOCKET_ERROR)
{
std::stringstream ss;
ss << "WSAEventSelect() failed with error : " << WSAGetLastError();
LOG_ERROR(ss.str());
return false;
}
++_eventCnt;
}
if(s_sock == INVALID_SOCKET)
return false;
int errorCode = bind(s_sock,(sockaddr*)&SockAddr,sizeof(SockAddr));
if(errorCode == SOCKET_ERROR)
{
bool stopListening = false;
_processSocketError(WSAGetLastError(), stopListening);
return false;
}
if(listen(s_sock,10)!=0)
{
return false;
}
return true;
}
If the peer dies there won't necessarily be any events at all. The only reliable way to detect a broken connection in TCP is to write to it. The first write to a broken connection will probably succeed but a later one will fail.
I found the solution to my problem. Now I am restarting all threads and sockets on reset in my application. After that i found server was not able to send because it was not able to connect new socket. I placed a infinite loop for trying to connect to client socket in my sendData() function. Which did the trick for me.