Windows Registered I/O Win 8.1 RioCreateRequestQueue Error 10045 - c++

Using Win8.1 and Visual Studio 2013, I’ve tested every example of Windows Registered I/O that I can find (about 5). All result in error 10045 on RioCreateRequestQueue() as shown below on one.
c:>rioServerTest.exe
InitialiseRio Start
InitialiseRio End
CreateCompletionQueue Start
CreateCompletionQueue End
CreateRequestQueue start
RIOCreateRequestQueue Error: 10045
Related code is :
void *pContext = 0;
printf("CreateRequestQueue start\n");
g_requestQueue = g_rio.RIOCreateRequestQueue(
g_socket, // Socket
(ULONG) 10, // MaxOutstandingReceive,
(ULONG) 1, // maxReceiveDataBuffers,
(ULONG) 10, // MaxOutstandingSend,
(ULONG) 1, // MaxSendDataBuffers
g_completionQueue, // ReceiveCQ
g_completionQueue, // SendCQ
pContext); // SocketContect
if (g_requestQueue == RIO_INVALID_RQ) {
printf_s("RIOCreateRequestQueue Error: %d\n", GetLastError());
exit(1);
}
printf("CreateRequestQueue End\n");
According to the literature that I have read, Registered I/O is intended to work with Windows 8 and later and Windows Server 2012 and later.
Can anyone explain to me via an example how to get this to work on Win8.1? TIA

10045 is WSAEOPNOTSUPP the description of which is "Operation not supported.
The attempted operation is not supported for the type of object referenced. Usually this occurs when a socket descriptor to a socket that cannot support this operation is trying to accept a connection on a datagram socket."
So actually it's likely that the code we need to see is in fact where you create your socket.
Your socket creation code should look something like this:
socket = ::WSASocket(
AF_INET,
SOCK_DGRAM,
IPPROTO_UDP,
NULL,
0,
WSA_FLAG_REGISTERED_IO);
I have some example articles (including a whole suite of RIO, UDP server designs with complete source code) here, all of these run on all operating systems that RIO supports.

Related

Can I write to a closed socket and forcefully correct the broken pipe error?

I have an application that runs on a large number of processors. On processor 0, I have a function that writes data to a socket if it is open. This function runs in a loop in a separate thread on processor 0, i.e. processor 0 is responsible for its own workload and has an extra thread running the communication on the socket.
//This function runs on a loop, called every 1.5 seconds
void T_main_loop(const int& client_socket_id, bool* exit_flag)
{
//Check that socket still connected.
int error_code;
socklen_t error_code_size = sizeof(error_code);
getsockopt(client_socket_id, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
if (error_code == 0)
{
//send some data
int valsend = send(client_socket_id , data , size_of_data , 0);
}
else
{
*(exit_flag) = false; //This is used for some external logic.
//Can I fix the broklen pipe here somehow?
}
}
When the client socket is closed, the program should just ignore the error, and this is standard behavior as far as I am aware.
However, I am using an external library (PETSc) that is somehow detecting the broken pipe error and closing the entire parallel (MPI) environment:
[0]PETSC ERROR: Caught signal number 13 Broken Pipe: Likely while reading or writing to a socket
I would like to leave the configuration of this library completely untouched if at all possible. Open to any robust workarounds that are possible.
By default, the OS sends the thread SIGPIPE if it tries to write into a (half) closed pipe or socket.
One option to disable the signal is to do signal(SIGPIPE, SIG_IGN);.
Another option is to use MSG_NOSIGNAL flag for send, e.g. send(..., MSG_NOSIGNAL);.

QUdpSocket bind failed

I'm having an issue with QT Udp sockets.
Assuming all headers are correctly included, I'm writing:
QUdpSocket* s = new QUdpSocket();
bool ok = s->bind(QHostAddress::Any, 8081);
if(!ok)
{
std::cout << "Cannot bind socket: " << s->errorString().toStdString() << std::endl;
}
The output is always
Cannot bind socket: operation is not supported
I made several attempts to solve this: tried disabling firewall, tried to bind specifing only the port, searching in internet, but the problem still remain.
My architecture is AMD64, Windows 7 installed
It is a platform specific issue, since a UnsupportedSocketOperationError is thrown.
/* 10 */
\value UnsupportedSocketOperationError The requested socket operation is
not supported by the local operating system (e.g., lack of
IPv6 support).
I solved by adding:
s->setProxy(QNetworkProxy::NoProxy);
before calling s->bind().

ZMQ doesn't work with the raw socket in Linux but works in Windows

I have a client program written with raw socket communicating with a server. It uses 'select' to poll the socket descriptor and get the message from the server. After getting message, I use a ZMQ socket to send the message out.
This works perfectly in windows. But in Linux, after I call the ZMQ 'send' function, I cannot receive message from the server any more. It seems the raw socket has been affected somehow.
The program is a multithread program but I have dealt with ZMQ carefully. The client program is running in a thread A and the ZMQ socket is only used by that thread A. I think I used ZMQ correctly as it is working well in Windows. But how comes the issue in Linux?
Anybody knows if this is normal? I am suspecting this is a ZMQ issue. As long as I remove the ZMQ 'send' function, the program works well. Anybody knows how to solve this issue? and why it is working well in Windows, not in Linux?
I found it doesn't work even in single thread situation. ZMQ creates more than ten threads automatically for me. I don't use any multithread this time, and the code flow is like this:
create a raw socket A;
connect to a business server B;
STATE = 1
while (raw socket A is connected){
if (STATE==1){
send(Request 1);
}else if (STATE==2){
send(Request 2);
}
int ret = select(fd + 1, &readSet, &writeSet, &errorSet, &timeout);
if (ret > 0){
if (FD_ISSET(fd, &readSet)) {
char buf[8192];
int nResult = receive( buf, sizeof(buf));
if (buf is X){
zmq.send(messageX)
STATE=2
}else if (buf is Y){
STATE=3
}else{...}
}// socket is ready for reading
}
}
After zmq.send(message), I cannot receive any new message!! The server side code is closed to me so that I cannot debug from server side. If I remove "zmq.send(message)", everything works fine. In Windows, this program works fine too.
Well, it is hard to tell u whats wrong without a code. But you should probably look at ZMQ versions in Linux and Windows because the "formats of sending" etc can differ between versions and stuff that works in one version will not in another.

Bluetooth with C++ and winsock

I'm finding it very hard to get information on Bluetooth communication in C++. Specifically I want to avoid using any third party libraries and I simply want to connect to a device already paired with my computer.
The device has already had its passcode entered and is available in the 'Show Bluetooth Devices' under my devices and printers. I'm using Windows 7 and visual studio 2013 professional for development in C++.
I've got some example code (from here http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedotherprotocol4k.html) which displays information on my Bluetooth radio and then displays device information and it seems to work well. Although it's printing out every Bluetooth device already paired with the computer, not ones which are within range, but that may be me misinterpreting what the code is suppose to do.
I've been looking through the Bluetooth reference page (http://msdn.microsoft.com/en-us/library/windows/desktop/aa362930%28v=vs.85%29.aspx) and all the functions are just to do with setting the Bluetooth radio availability and other things like that; no sign of connecting to a found device at all.
I must be missing something, using wrong key words when Googling or something, because I've found nothing about connecting to a Bluetooth device!
If anyone has any suggestions, code, or links that would be great! I can connect to my device using the serial functionality (very easily) but I have to manually enter the COM port it's registered on, which isn't very user friendly. I want to scan and select, or enter a Bluetooth device name, and connect that way.
Cheers
EDIT:
BitBanks answer pointed me in the right direction. Only thing missing was a WSAStartup request before any socket requests:
WORD wVersionRequested;
WSADATA wsaData;
int err;
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
wVersionRequested = MAKEWORD(2, 2);
err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
/* Tell the user that we could not find a usable */
/* Winsock DLL. */
printf("WSAStartup failed with error: %d\n", err);
return 1;
}
If you have a bluetooth address from discovery or the paired-devices list, you can connect to it like this (error checking needs to be added):
#include <winsock2.h>
#include <ws2bth.h>
SOCKADDR_BTH sockAddr;
SOCKET btSocket;
int error;
btSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
memset (&sockAddr, 0, sizeof(sockAddr));
sockAddr.addressFamily = AF_BTH;
sockAddr.serviceClassId = RFCOMM_PROTOCOL_UUID;
sockAddr.port = BT_PORT_ANY;
sockAddr.btAddr = <your bluetooth address>
error = connect(btSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr));
Some devices advertise the SerialPortServiceClass_UUID instead of the RFCOMM_PROTOCOL_UUID. You also may need to retry the connection several times. Certain poorly implemented bluetooth devices (cough PowerA Moga cough) require multiple tries to connect.
This may not be the official way to do it, but I get the 6-byte BT address of the device I'm interested in from the paired list like this:
unsigned char *p;
ULONGLONG ullAddr;
p = (unsigned char *)pwsaResults->lpcsaBuffer->RemoteAddr.lpSockaddr; // point to addr
memcpy(&ullAddr, &p[2], 8); // copy Bluetooth address of device we found

Tracking down the source of handle leaks in WinSock MFC application

We are developing an application in which we are using a WinSock-based sime socket approach to communicate with an outside module. Our requirement is to make sure that the connection will always be on, so for that reason, we continuously retry to connect every 1 minute whenever we get disconnected.
Our problem starts here. We have observered that on every retry of socket reconnect, it is leaking exactly two Windows handles. We have tried so many options, but none of them are working. Which handles could be leaking, and how could we go about identifying the culprit?
Following is the code that we are using right now:
bool CSocketClass::ConnectToServer(int nLineNo)
{
string strIPAddress;
int nPortNo;
SOCKET* l_ClientSocket;
int ConnectionResult;
//----------------------
// Create a SOCKET for connecting to server
if (nLineNo == 1)
{
m_objLine1.m_ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
strIPAddress = m_objLine1.m_strIPAddress;
nPortNo = m_objLine1.m_nPortNo;
l_ClientSocket = &(m_objLine1.m_ClientSocket);
}
else
{
m_objLine2.m_ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
strIPAddress = m_objLine2.m_strIPAddress;
nPortNo = m_objLine2.m_nPortNo;
l_ClientSocket = &(m_objLine2.m_ClientSocket);
}
if(INVALID_SOCKET == *l_ClientSocket)
{
return false;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( strIPAddress.c_str() );
clientService.sin_port = htons( nPortNo );
//----------------------
// Connect to server.
ConnectionResult = connect( *l_ClientSocket, (SOCKADDR*) &clientService, sizeof(clientService) ) ; if (ConnectionResult == SOCKET_ERROR)
{
if (nLineNo == 1)
{
//ERROR in line1
}
else
{
//ERROR in line2
}
return false;
}
else
//In case of successful connection
{
//Other actions
}
return true;
}
Try the free Process Explorer from Microsoft. It will display all the open handles for a process along with information such as name (for file, mutex, event, etc. handles). It will also highlight newly created and closed handles, so if you step through a loop of your code and refresh the display, you can see the exact handles that were leaked.
Let's say you acquired socket correctly:
m_objLine1.m_ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
m_objLine1.m_ClientSocket != INVALID_SOCKET // true
but then, you can't connect, so
ConnectionResult = connect( *l_ClientSocket, (SOCKADDR*) &clientService,
sizeof(clientService) )
ConnectionResult == SOCKET_ERROR // true
in that case, you should close that acquired socket handle:
closesocket(m_objLine1.m_ClientSocket);
You have two lines, so I guess that you call this function twice, once for each line, so
that's why two leaked handles.
I would suggest that you try Intel Parallel Inspector in order to identify the memory leaks and where they are occurring.
There is a trial download if you wish to try it.
A simple way to find handle leaks is to log everything.
Every time you obtain a handle, log that you obtained it, as well as any other details about the circumstances. Every time you release a handle, log that you released it. Include both times the actual handle (just some hex).
Then you get a log that looks like this (just for example):
Obtained handle 0xf000 (nLineNo = 5)
Obtained handle 0xb000 (nLineNo = 6)
Obtained handle 0xd0d0 (nLineNo = 7)
Released handle 0xf000
Released handle 0xb000
Picking through this by hand, you can see that you obtained handle 0xd0d0 when nLineNo was 7, and it never got released. It's not much but it does help, and if the going gets tough, you can even try logging stack traces at each obtain/release. Also, if the log is always reliably produced like that, you can start putting in breakpoints based on the actual values (e.g. break at a point in the program when the handle is 0xd0d0, so you can see what's happening to it).
If it's more practical, you can start wrapping your handles inside the program itself, e.g. a std::set of all obtained handles, along with any details about when they were obtained, and you can effectively start hacking your program to keep track of what it's doing (then undo all your changes once you fixed it).
Hope that helps - it's part of the reason I tend to at least keep a std::set of everything I obtain, so if worst comes to worst you can iterate over them on shutdown and release them all (and log a big "FIX THIS!" message!)
Try adding a shutdown(SD_BOTH) on the socket handles after the closesocket(); Also, try adding a Sleep for about 100ms (only for a test) and see how it goes.