I have a problem with my program. I wanted it to have two threads, one of them listening for connections, and the other one receiving data from them... Unfortunately, it acts strangely. It will ignore my cout and cin usage everywhere in the code, so I can't even debug it. May I ask that someone sheds some light on it? Thank you in advance.
#include <windows.h>
#include <iostream.h>
#include <string.h>
#include <cstdlib>
int ConnectionNum, Port=4673;
WSADATA wsaData;
SOCKET Connections[256];
DWORD WINAPI ReceiveThread(LPVOID iValue)
{
//this is going to be receiving TCP/IP packets, as soon as the connection works
}
DWORD WINAPI ListenThread(LPVOID iValue) //this thread is supposed to listen for new connections and store them in an array
{
SOCKET ListeningSocket;
SOCKET NewConnection;
SOCKADDR_IN ServerAddr;
SOCKADDR_IN ClientAddr;
int ClientAddrLen;
WSAStartup(MAKEWORD(2,2), &wsaData);
ListeningSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_port=htons(Port);
ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);
bind(ListeningSocket, (SOCKADDR*)&ServerAddr, sizeof(ServerAddr));
if(listen(ListeningSocket, 5)!=0)
{
cout << "Could not begin listening for connections.";
return 0;
}
ConnectionNum=0;
while(ConnectionNum<256)
{
Connections[ConnectionNum]=accept(ListeningSocket, (SOCKADDR*)&ClientAddr, &ClientAddrLen);
ConnectionNum++;
cout << "New connection.";
}
}
int main()
{
HANDLE hThread1,hThread2;
DWORD dwGenericThread;
char lszThreadParam[3];
hThread1=CreateThread(NULL, 0, ListenThread, &lszThreadParam, 0, &dwGenericThread);
if(hThread1==NULL)
{
DWORD dwError=GetLastError();
cout<<"SCM:Error in Creating thread"<<dwError<<endl ;
return 0;
}
hThread2=CreateThread(NULL, 0, ReceiveThread, &lszThreadParam, 0, &dwGenericThread);
if(hThread2==NULL)
{
DWORD dwError=GetLastError();
cout<<"SCM:Error in Creating thread"<<dwError<<endl ;
return 0;
}
system("pause"); //to keep the entire program from ending
}
I don't see any cin calls here. As for the calls to cout, you may have to flush the output, as it is being called in a separate thread. You can do this by simply calling std::endl:
cout << "New connection." << std::endl;
The reason that your cout calls aren't showing up is possibly because you're supplying the wrong parameters to the linker. Are you specifying /SUBSYSTEM:CONSOLE ? (System tab of the Linker properties). If not then you're not telling the operating system to create a console for the program, you may be telling it it's a windows program, and if you program doesn't have a console then you wont see your programs cout output...
Once you can see your debug...
I assume you are connecting to your test program from a client of some sort? Nothing will happen until you connect to your program which will cause the call to Accept() to return.
By the way, system("pause"); is probably the worst way to achieve what you want but I assume you're only doing that because you can't get cin to work...
Related
I am having some problems with inter process communication in ZMQ between several instances of a program
I am using Linux OS
I am using zeromq/cppzmq, header-only C++ binding for libzmq
If I run two instances of this application (say on a terminal), I provide one with an argument to be a listener, then providing the other with an argument to be a sender. The listener never receives a message. I have tried TCP and IPC to no avail.
#include <zmq.hpp>
#include <string>
#include <iostream>
int ListenMessage();
int SendMessage(std::string str);
zmq::context_t global_zmq_context(1);
int main(int argc, char* argv[] ) {
std::string str = "Hello World";
if (atoi(argv[1]) == 0) ListenMessage();
else SendMessage(str);
zmq_ctx_destroy(& global_zmq_context);
return 0;
}
int SendMessage(std::string str) {
assert(global_zmq_context);
std::cout << "Sending \n";
zmq::socket_t publisher(global_zmq_context, ZMQ_PUB);
assert(publisher);
int linger = 0;
int rc = zmq_setsockopt(publisher, ZMQ_LINGER, &linger, sizeof(linger));
assert(rc==0);
rc = zmq_connect(publisher, "tcp://127.0.0.1:4506");
if (rc == -1) {
printf ("E: connect failed: %s\n", strerror (errno));
return -1;
}
zmq::message_t message(static_cast<const void*> (str.data()), str.size());
rc = publisher.send(message);
if (rc == -1) {
printf ("E: send failed: %s\n", strerror (errno));
return -1;
}
return 0;
}
int ListenMessage() {
assert(global_zmq_context);
std::cout << "Listening \n";
zmq::socket_t subscriber(global_zmq_context, ZMQ_SUB);
assert(subscriber);
int rc = zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);
assert(rc==0);
int linger = 0;
rc = zmq_setsockopt(subscriber, ZMQ_LINGER, &linger, sizeof(linger));
assert(rc==0);
rc = zmq_bind(subscriber, "tcp://127.0.0.1:4506");
if (rc == -1) {
printf ("E: bind failed: %s\n", strerror (errno));
return -1;
}
std::vector<zmq::pollitem_t> p = {{subscriber, 0, ZMQ_POLLIN, 0}};
while (true) {
zmq::message_t rx_msg;
// when timeout (the third argument here) is -1,
// then block until ready to receive
std::cout << "Still Listening before poll \n";
zmq::poll(p.data(), 1, -1);
std::cout << "Found an item \n"; // not reaching
if (p[0].revents & ZMQ_POLLIN) {
// received something on the first (only) socket
subscriber.recv(&rx_msg);
std::string rx_str;
rx_str.assign(static_cast<char *>(rx_msg.data()), rx_msg.size());
std::cout << "Received: " << rx_str << std::endl;
}
}
return 0;
}
This code will work if I running one instance of the program with two threads
std::thread t_sub(ListenMessage);
sleep(1); // Slow joiner in ZMQ PUB/SUB pattern
std::thread t_pub(SendMessage str);
t_pub.join();
t_sub.join();
But I am wondering why when running two instances of the program the code above won't work?
Thanks for your help!
In case one has never worked with ZeroMQ,one may here enjoy to first look at "ZeroMQ Principles in less than Five Seconds"before diving into further details
Q : wondering why when running two instances of the program the code above won't work?
This code will never fly - and it has nothing to do with thread-based nor the process-based [CONCURENT] processing.
It was caused by a wrong design of the Inter Process Communication.
ZeroMQ can provide for this either one of the supported transport-classes :{ ipc:// | tipc:// | tcp:// | norm:// | pgm:// | epgm:// | vmci:// } plus having even smarter one for in-process comms, an inproc:// transport-class ready for inter-thread comms, where a stack-less communication may enjoy the lowest ever latency, being just a memory-mapped policy.
The selection of L3/L2-based networking stack for an Inter-Process-Communication is possible, yet sort of the most "expensive" option.
The Core Mistake :
Given that choice, any single processes ( not speaking about a pair of processes ) will collide on an attempt to .bind() its AccessPoint onto the very same TCP/IP-address:port#
The Other Mistake :
Even for the sake of a solo programme launched, both of the spawned threads attempt to .bind() its private AccessPoint, yet none does an attempt to .connect() a matching "opposite" AccessPoint.
At least one has to successfully .bind(), and
at least one has to successfully .connect(), so as to get a "channel", here of the PUB/SUB Archetype.
ToDo:
decide about a proper, right-enough Transport-Class ( best avoid an overkill to operate the full L3/L2-stack for localhost/in-process IPC )
refactor the Address:port# management ( for 2+ processes not to fail on .bind()-(s) to the same ( hard-wired ) address:port#
always detect and handle appropriately the returned {PASS|FAIL}-s from API calls
always set LINGER to zero explicitly ( you never know )
I'm quite new to C++/C in general, so execuse me if this question might appear kinda stupid, but i'm really stuck here.
What I'm trying to do is a simple tcp server giving the user the opportunity to accept/decline incoming connections. I have a function named waitingForConnection() containing the main loop. It's called in the main function after the socket is sucessuflly bind and marked as passive.
What I'd expect is that, after the Client connects to the server, the function handleConnection() is getting called, causing the main loop to wait until the function is executed and only then to contiue.
But what actually seems to happen is that the main loop continues to the next accept() call, which is blocking the thread, before handleConnection() is completley executed. The test-output "done" will only become visible if the client connects a second time and the thread wakes up again.
To me it seem like the code is executed completley out of order, which I believe is not possible, since the whole code should be executed in a single thread.
Console Output after first connection attempt ("n" is user input):
"Accept connection ? (y/n)"n
Console Output after second connection attempt:
"Accept connection ? (y/n)"n
"doneAccept connection ? (y/n)"
Please note that I'm not looking for any workaround using select() or something similar, I'm just trying to understand why the code does what it does and maybe how to fix it by changing the structure.
int soc = socket(AF_INET, SOCK_STREAM, 0);
void handleConnection(int connectionSoc, sockaddr_in client){
string choice;
cout<<"Accept connection ? (y/n)";
cin>>choice;
if(choice=="y"||choice == "Y"){
//do something here
}else{
close(connectionSoc);
}
cout<<"done";
}
void waitingForConnection(){
while(running){
sockaddr_in clientAddress;
socklen_t length;
length = sizeof(clientAddress);
int soc1 = accept(soc,(struct sockaddr*)&clientAddress, &length);
if(soc1<0){
statusOutput("Connection failed");
}else{
handleConnection(soc1, clientAddress);
}
}
}
Problem is that output to std::cout is buffered and you simply do not see that until it is flushed. As std::cin automatically flushes std::cout you get your output on the next input. Change your output to:
std::cout << "done" << std::endl;
and you would get expected behavior.
I have the given code:
#include <winsock2.h>
#include <sys/time.h>
#include <iostream>
int main()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
std::cout << "WSA Initialization failed!" << std::endl;
WSACleanup();
}
timeval time;
time.tv_sec = 1;
time.tv_usec = 0;
int retval = select(0, NULL, NULL, NULL, &time);
if (retval == SOCKET_ERROR)
{
std::cout << WSAGetLastError() << std::endl;
}
return 0;
}
It prints 10022, which means error WSAEINVAL. According to this page, I can get this error only if:
WSAEINVAL: The time-out value is not valid, or all three descriptor parameters were null.
However, I have seen a few examples calling select() without any FD_SETs. Is it possible somehow? I need to do it in a client-side code to let the program sleep for short periods while it is not connected to the server.
However, I have seen a few examples calling select() without any
FD_SETs.
It will work in most OS's (that aren't Windows).
Is it possible somehow [under Windows]?
Not directly, but it's easy enough to roll your own wrapper around select() that gives you the behavior you want even under Windows:
int proper_select(int largestFileDescriptorValuePlusOne, struct fd_set * readFS, struct fd_set * writeFS, struct fd_set * exceptFS, struct timeVal * timeout)
{
#ifdef _WIN32
// Note that you *do* need to pass in the correct value
// for (largestFileDescriptorValuePlusOne) for this wrapper
// to work; Windows programmers sometimes just pass in a dummy value,
// because the current Windows implementation of select() ignores the
// parameter, but that's a portability-killing hack and wrong,
// so don't do it!
if ((largestFileDescriptorValuePlusOne <= 0)&&(timeout != NULL))
{
// Windows select() will error out on a timeout-only call, so call Sleep() instead.
Sleep(((timeout->tv_sec*1000000)+timeout->tv_usec)/1000);
return 0;
}
#endif
// in all other cases we just pass through to the normal select() call
return select(maxFD, readFS, writeFS, exceptFS, timeout);
}
... then just call proper_select() instead of select() and you're golden.
From the notorious and offensive Winsock 'lame list':
Calling select() with three empty FD_SETs and a valid TIMEOUT structure as a sleezy delay function.
Inexcusably lame.
Note the mis-spelling. The document is worth reading, if you can stand it, just to see the incredible depths hubris can attain. In case they've recanted, or discovered that they didn't invent the Sockets API, you could try it with empty FD sets instead of null parameters, but I don't hold out much hope.
I have simple TCP server that is lessening for connections.
UINT MTServerThread(LPVOID pParam)
{
FILELog::ReportingLevel() = logINFO;
WSADATA wsaData;
sockaddr_in local;
int wsaret=WSAStartup(0x101,&wsaData);
if(wsaret!=0)
{
return 0;
}
local.sin_family=AF_INET;
local.sin_addr.s_addr=INADDR_ANY;
local.sin_port=htons((u_short)20248);
server=socket(AF_INET,SOCK_STREAM,0);
if(server==INVALID_SOCKET)
{
return 0;
}
if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
{
return 0;
}
if(listen(server,10)!=0)
{
return 0;
}
SOCKET client;
sockaddr_in from;
int fromlen=sizeof(from);
while(true)
{
FILE_LOG(logINFO)<<"connecting";
client=accept(server,(struct sockaddr*)&from,&fromlen);
if (client==INVALID_SOCKET)
{
int g = WSAGetLastError();
FILE_LOG(logINFO)<<"invalid socket code "<<g;
}
AfxBeginThread(ClientThread,(LPVOID)client);
}
return 0;
}
I need to use third party compiled DLL library that is also making its own tcp communication not related to my server and acts like client. After creating library class object and using it for some procedures that are related to its own (library) TCP comunication I have breakpoint dropped on line int g = WSAGetLastError();. Result of last error is 10004.
That means:
WSAEINTR
10004
Interrupted function call.
A blocking operation was interrupted by a call to WSACancelBlockingCall.
Is it possible that code in dll can affect my TCP server? I have dll source code, but I cant't find call to WSACancelBlockingCall in it.
How to start to solve this problem?
You are using Winsock 1.1 and WSACancelBlockingCall() does apply to that version of Winsock. But since you cannot find WSACancelBlockingCall() in the DLL source code, then obviously it not actually using it.
Try updating your app to use Winsock 2.0+ instead (just change your first parameter to WSAStartup()) and see if the problem goes away. WSACancelBlockingCall() was removed in Winsock 2.0.
If you are still encountering the problem, then the most likely culprit is a firewall/antivirus program running on your machine and interfering with the connection.
BTW, you should not be calling AfxBeginThread() if accept() fails, since there is no connection for your thread to manage.
I think you are my last hope. I have got here a Bluetooth device (it is a sensor to be more precisely) which I want to connect to and read data from. The device offers SPP (Serial Port Profile). To avoid the problem of reliable mapping from Bluetooth addresses and virtual serial ports (COM Ports), I am going to use sockets.
Unfortunately the application always crashes before returning from WinAPI function connect(...) with: 0xC0000005: Access violation reading location 0x00000004, so I get no error code.
BUT, and that is weird, when I right-click on the Bluetooth System Tray Icon to to show available devices, my device shows up being authenticated and connected. This list was empty before, of course.
My OS is Windows 7 64 Bit, the IDE is Visual Studio 2010, Microsoft Bluetooth Stack. Code to find and connect to my only device:
#include <iostream>
#include <string>
#include <algorithm>
#include <cassert>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <BluetoothAPIs.h>
#include <Winsock2.h>
#include <Ws2bth.h>
BOOL auth_callback_ex(LPVOID pvParam, PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS authParams)
{
BLUETOOTH_AUTHENTICATE_RESPONSE response;
response.bthAddressRemote = authParams->deviceInfo.Address;
response.authMethod = authParams->authenticationMethod; // == BLUETOOTH_AUTHENTICATION_METHOD_LEGACY
UCHAR pin[] = "1234";
std::copy(pin, pin+sizeof(pin), response.pinInfo.pin);
response.pinInfo.pinLength = sizeof(pin)-1; //excluding '\0'
response.negativeResponse = false;
HRESULT err = BluetoothSendAuthenticationResponseEx(NULL, &response);
if (err)
{
std::cout << "BluetoothSendAuthenticationResponseEx error = " << err << std::endl;
}
return true;
}
int main()
{
BLUETOOTH_DEVICE_SEARCH_PARAMS btSearchParams;
btSearchParams.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS);
btSearchParams.cTimeoutMultiplier = 5; //5*1.28s search timeout
btSearchParams.fIssueInquiry = true; //new inquiry
//return all known and unknown devices
btSearchParams.fReturnAuthenticated = true;
btSearchParams.fReturnConnected = true;
btSearchParams.fReturnRemembered = true;
btSearchParams.fReturnUnknown = true;
btSearchParams.hRadio = NULL; //search on all local radios
BLUETOOTH_DEVICE_INFO btDeviceInfo;
ZeroMemory(&btDeviceInfo, sizeof(BLUETOOTH_DEVICE_INFO)); //"initialize"
btDeviceInfo.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);
HBLUETOOTH_DEVICE_FIND btDeviceFindHandle = NULL;
btDeviceFindHandle = BluetoothFindFirstDevice(&btSearchParams, &btDeviceInfo);
if(btDeviceFindHandle)
{
HBLUETOOTH_AUTHENTICATION_REGISTRATION authCallbackHandle = NULL;
DWORD err = BluetoothRegisterForAuthenticationEx(&btDeviceInfo, &authCallbackHandle, &auth_callback_ex, NULL);
if (err != ERROR_SUCCESS)
{
DWORD err = GetLastError();
std::cout << "BluetoothRegisterForAuthentication Error" << err << std::endl;
}
/////////////// Socket
WSADATA wsaData;
err = WSAStartup(MAKEWORD(2,2), &wsaData);
if (err)
{
std::cout << "WSAStartup error = " << err << std::endl;
}
// create BT socket
SOCKET s = socket (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
assert(s != INVALID_SOCKET); //WSAGetLastError //throw // runtime check release?
SOCKADDR_BTH btSockAddr;
btSockAddr.addressFamily = AF_BTH;
btSockAddr.btAddr = btDeviceInfo.Address.ullLong;
btSockAddr.serviceClassId = RFCOMM_PROTOCOL_UUID; //SerialPortServiceClass_UUID (no difference)
btSockAddr.port = BT_PORT_ANY;
err = connect(s, reinterpret_cast<SOCKADDR*>(&btSockAddr), sizeof(SOCKADDR_BTH));
/* <--- never got so far --> */
if (err)
{
DWORD wsaErr = WSAGetLastError();
std::cout << "connect error = " << wsaErr << std::endl;
}
else
{
//err = shutdown(s, SD_BOTH);
err = closesocket(s);
if (err)
{
std::cout << "closesocket error = " << err << std::endl;
}
}
WSACleanup();
///////////////Socket
BOOL ok = BluetoothUnregisterAuthentication(authCallbackHandle);
if (!ok)
{
DWORD err = GetLastError();
std::cout << "BluetoothUnregisterAuthentication Error" << err << std::endl;
}
ok = BluetoothFindDeviceClose(btDeviceFindHandle);
if (!ok)
{
DWORD err = GetLastError();
std::cout << "BluetoothDeviceClose Error" << err << std::endl;
}
}
else
{
DWORD err = GetLastError();
std::cout << "BluetoothFindFirstDevice Error" << err << std::endl;
}
std::cin.get();
}
I have made some few more observations:
The authentication callback and the BluetoothSendAuthenticationResponseEx function are working fine, there is no error given back.
If I do not install the authentication callback (BluetoothRegisterForAuthenticationEx) and therefore have to manually enter the PIN (the UI shows up automatically while trying to connect), connect function returns properly and everything works fine, too. I even got data (the recv part is omitted in this snippet).
If I search and pair completely manually (Bluetooth Tray Icon -> Add Device), everything is fine, too. A service and a virtual serial port is installed. Data come via putty.
So somewhere between calling the authentication callback and end of the connect function something is going wrong. Maybe when trying to get a certain structure data via a pointer, which should not be NULL, plus offset.
Or am I doing something wrong? Is there something missing?
Thanks...
The problem is that your function is using the wrong calling convention. According to MSDN, you need to use the CALLBACK macro, as in:
BOOL CALLBACK auth_callback_ex(LPVOID pvParam, PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS authParams)
Having the wrong calling convention will result in a stack mismatch on return, which could cause an access violation inside the MS Bluetooth code when it can't find its local variables.
Or it could result in the parameters to your function being all jumbled. If authParams and pvParam are swapped, because the cdecl calling convention expects args pushed from right to left and stdcall pushes them left to right, you'd get NULL in authParams, and then authParams->deviceInfo.Address will try to read address 0x04.
The compiler should have caught this. Compile with maximum warnings turned on (/W4). You'll have to ignore the warnings about unknown pragma, this is a bug in the header which I'm reporting to Microsoft (misspelled #pragma deprecated).
Unfortunately there's a second bug in the header, much more serious, of not specifying the calling convention explicitly, with the result that it will only work correctly on x86 (32-bit code) if /Gz is used. Yuck!
Followup: In the SDK headers shipped with VS2013, both issues are fixed.
You have a null-pointer access somewhere. "Access violation reading location 0x00000004" indicates that, as it is only 4 bytes away from zero.
I have a couple of thoughts to share with you, but be advised that these are hunches. I haven't compiled and debugged your code, although I commend you for posting a complete sample.
I think the crash may be within your authentication callback function, due to a '''NULL''' pointer dereference.
These lines:
response.bthAddressRemote = authParams->deviceInfo.Address;
response.authMethod = authParams->authenticationMethod; // == BLUETOOTH_AUTHENTICATION_METHOD_LEGACY
will cause the message you describe, if you are running on 32-bit Windows, and '''authParams''' may be '''NULL''' -- in that case, '''deviceInfo''' contributes a zero offset (it is at the beginning of the '''BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS'''), and '''.Address''' does contribute an offset of 4 ('''NULL + 4 == 0x00000004'''), because it follows a '''DWORD''' and nothing else within the '''BLUETOOTH_DEVICE_INFO''' layout.
Is it possible that '''authParams''' is NULL when your callback is called?
As another poster has already mentioned, this could be due to incorrect calling convention (lack of '''CALLBACK''' macro) -- causing otherwise correct parameters to mis-align with the positions the compiled code is reading.
The second thought was:
BLUETOOTH_DEVICE_INFO btDeviceInfo;
ZeroMemory(&btDeviceInfo, sizeof(BLUETOOTH_DEVICE_INFO)); //"initialize"
btDeviceInfo.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);
Can be represented by:
BLUETOOTH_DEVICE_INFO btDeviceInfo = {sizeof(BLUETOOTH_DEVICE_INFO)};
According to the standard, this will zero the other fields of '''btDeviceInfo'''.
Or write managed code and use my Bluetooth library 32feet.NET Super simple. http://32feet.codeplex.com/
Will it crash then -- if so there's something wrong on your PC...