I try to use a thread to tell the user the COM port for serial communication he entered was wrong. I have a thread class which tries to establish the connection and a function in my main, that should tell the user.
The compiler does not complain, but my program never enters the function. Maybe anyone can spot the mistake I made.
main.cpp:
WindowsDgpsGUIFrame::WindowsDgpsGUIFrame(wxWindow* parent,wxWindowID id)
{
...
Bind(wxEVT_THREAD, &WindowsDgpsGUIFrame::onConnectionFailed, this, wxID_EXIT);
...
}
void WindowsDgpsGUIFrame::OnButtonStartClick(wxCommandEvent& event)
{
NavigationThread* navigationThread = new NavigationThread(this, m_usedVariables);
m_navigationThread = navigationThread;
wxThreadError err = m_navigationThread->Create();
if(err != wxTHREAD_NO_ERROR)
{
StaticStatusText->Enable();
StaticStatusText->SetLabel("Could not create NavigationThread.");
}
else{
StaticStatusText->SetLabel("Thread created");
}
err = m_navigationThread->Run();
if(err != wxTHREAD_NO_ERROR)
{
StaticStatusText->SetLabel("Could not run thread.");
}
}
void WindowsDgpsGUIFrame::onConnectionFailed(wxThreadEvent& event)
{
StaticConnectionText->SetLabel(event.GetString());
}
thread.cpp:
wxThread::ExitCode NavigationThread::Entry()
{
Serial serial;
int resultGnss = serial.Open(m_gnssPort, STANDARD_BAUDRATE);
wxThreadEvent event(wxEVT_THREAD, wxID_RETRY);
if(resultGnss != 0)
{
event.SetString("Connection to GNSS box not possible. Try with another COM port.");
m_parent->GetEventHandler()->AddPendingEvent(event);
}
else{
event.SetString("Connection successful");
m_parent->GetEventHandler()->AddPendingEvent(event);
}
return 0;
}
The thread gets created and starts running, but even though the event is thrown in the thread the program never reaches onConnectionFailed().
Related
I stayed many days to find where the error is and I'm stuck.Can anyone help me please.
MY application is a clustering program in NS3 that was written from one else and free to anyone.
The program is run and no errors and print messages but always the number of neighbors in every Cluster Head CH is zero, this mean that the hellow messages are not reach every node and every node consider itself as cluster head because it dosn't see any neighbor node!. every node (vehicle) has two sockets one for send data m_socket and one for listening m_socketlistening, the code is:
if (!m_socket)
{
// TypeId::LookupByName ("ns3::UdpSocketFactory
TypeId m_tid = TypeId::LookupByName("ns3::UdpSocketFactory");
//m_socket = Socket::CreateSocket(GetNode() , TypeId::LookupByName("ns3::UdpSocketFactory"));
m_socket = Socket::CreateSocket(GetNode(), m_tid);
// i added the down line
// InetSocketAddress remote = InetSocketAddress(Ipv4Address::GetBroadcast(),80);
if (Inet6SocketAddress::IsMatchingType(m_peer))
{
m_socket->Bind6();
}
else if (InetSocketAddress::IsMatchingType(m_peer)
|| PacketSocketAddress::IsMatchingType(m_peer))
{
m_socket->Bind();
}
m_socket->SetAllowBroadcast(true);
m_socket->ShutdownRecv();
m_socket->SetConnectCallback(
MakeCallback(&V2vControlClient::ConnectionSucceeded, this),
MakeCallback(&V2vControlClient::ConnectionFailed, this));
//m_socket->Connect(Ipv4Address::GetBroadcast());
m_socket->Connect(m_peer);
}
now this is a part pf the listening socket creation
if (!m_socketListening)
{
NS_LOG_UNCOND("\n ...creating socket muhsen...");
m_socketListening = Socket::CreateSocket(GetNode(), m_tidListening);
m_socketListening->Bind(m_peerListening);
m_socketListening->Listen();
m_socketListening->ShutdownSend();
if (addressUtils::IsMulticast(m_peerListening))
{
Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket>(m_socketListening);
if (udpSocket)
{
// equivalent to setsockopt (MCAST_JOIN_GROUP)
udpSocket->MulticastJoinGroup(0, m_peerListening);
}
else
{
NS_FATAL_ERROR("Error: joining multicast on a non-UDP socket");
}
}
}
m_socketListening->SetRecvCallback(MakeCallback(&V2vControlClient::HandleRead, this));
m_socketListening->SetAcceptCallback(
MakeNullCallback<bool, Ptr<Socket>, const Address &>(),
MakeCallback(&V2vControlClient::HandleAccept, this));
m_socketListening->SetCloseCallbacks(
MakeCallback(&V2vControlClient::HandlePeerClose, this),
MakeCallback(&V2vControlClient::HandlePeerError, this));
void V2vControlClient::HandleRead (Ptr<Socket> socket)
{
NS_LOG_UNCOND("\n this message is never executed..");
NS_LOG_FUNCTION (this << socket);
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom(from)))
{
if (packet->GetSize() == 0)
{ //EOF
break;
}
When i run the application the first statement after the HandleRead Function which is
NS_LOG_UNCOND("\n this message is never executed..");
is never printed when run the program, this means that the handle read is never executed.
Any help is very appreciate!
There is zero documentation how to do an async bidirectional stream with grpc. I've made guesses by piecing together the regular async examples with what I found in peope's github.
With the frankestein code I have, I cannot figure out how to tell when a client sent me a message. Here is the procedure I have running on its own thread.
void GrpcStreamingServerImpl::listeningThreadProc()
{
try
{
// I think we make a call to the RPC method and wait for others to stream to it?
::grpc::ServerContext context;
void * ourOneAndOnlyTag = reinterpret_cast<void *>(1); ///< Identifies the call we are going to make. I assume we can only handle one client
::grpc::ServerAsyncReaderWriter<mycompanynamespace::OutputMessage,
mycompanynamespace::InputMessage>
stream(&context);
m_service.RequestMessageStream(&context, &stream, m_completionQueue.get(), m_completionQueue.get(), ourOneAndOnlyTag);
// Now I'm going to loop and get events from the completion queue
bool keepGoing = false;
do
{
void* tag = nullptr;
bool ok = false;
const std::chrono::time_point<std::chrono::system_clock> deadline(std::chrono::system_clock::now() +
std::chrono::seconds(1));
grpc::CompletionQueue::NextStatus nextStatus = m_completionQueue->AsyncNext(&tag, &ok, deadline);
switch(nextStatus)
{
case grpc::CompletionQueue::NextStatus::TIMEOUT:
{
keepGoing = true;
break;
}
case grpc::CompletionQueue::NextStatus::GOT_EVENT:
{
keepGoing = true;
if(ok)
{
// This seems to get called if a client connects
// It does not get called if we didn't call 'RequestMessageStream' before the loop started
// TODO - How do we tell when the client send us a messages?
// TODO - How do we know if they are just connecting?
// TODO - How do we get the message client sent?
// The tag corresponds to the request we made
if(tag == reinterpret_cast<void *>(1))
{
// SNIP successful writing of a message
stream.Write(*(outputMessage.get()), reinterpret_cast<void*>(2));
}
else if(tag == reinterpret_cast<void *>(2))
{
// This is telling us the message we sent was completed
}
else
{
// TODO - I dunno what else it can be
}
}
break;
}
case grpc::CompletionQueue::NextStatus::SHUTDOWN:
{
keepGoing = false;
break;
}
}
} while(keepGoing);
// Completion queue was shutdown
}
catch(std::exception& e)
{
QString errorMessage(
QString("An std::exception was caught in the listening thread. Exception message: %1").arg(e.what()));
m_backPointer->onImplError(errorMessage);
}
catch(...)
{
QString errorMessage("An exception of unknown type, was caught in the listening thread.");
m_backPointer->onImplError(errorMessage);
}
}
Setup looked like this
// Start up the grpc service
grpc::ServerBuilder builder;
builder.RegisterService(&m_service);
builder.AddListeningPort(endpoint.toStdString(), grpc::InsecureServerCredentials());
m_completionQueue = builder.AddCompletionQueue();
m_server = builder.BuildAndStart();
// Start the listening thread
m_listeningThread = QThread::create(&GrpcStreamingServerImpl::listeningThreadProc, this);
I use blocking server-client to do a FTP homework.
But i got stuck when try to put Accept into a thread. (Everytime i run the CServer , it crahses and shut down)
Anyone know the answer or can suggest me sth else. i really appreciate it.
I really want to use blocking and CSocket ,so dont't suggest me non-blocking
I also took a look at p_thread, but i still won't if any chance my code works
void CServerDlg::OnBnClickedListen()
{
// TODO: Add your control notification handler code here
if (listen.Create(PORT, SOCK_STREAM, _T("127.0.0.1")) == 0) {
showMessage("Failed to init socket");
listen.GetLastError();
return;
}
else {
if (listen.Listen(1) == FALSE) {
showMessage("Can't listen to the port");
listen.Close();
return;
}
}
connectThread = thread(&CServerDlg::ThreadMain, this);
}
void CServerDlg::ThreadMain() {
int cnt = -1;
CSocket* client;
while (1)
{
client = new CSocket();
if (listen.Accept(*client)) // it crashes everytime i got here
{
cnt++;
char * id = Converter::StringToChar(Converter::NumberToString(*client));
clients.push_back(client);
ClientId.push_back(id);
showMessage("Found a connection with client " + Converter::CharToString(id));
/*
Thread here
*/
threads.push_back(thread(&CServerDlg::ThreadProc, this, cnt));
}
else break;
}
}
consider the next piece of code -
int get_ready_connection(int s) {
/* socket of connection */
int caller;
if ((caller = accept(s,NULL,NULL)) < SUCCESS)
{
server_log->write_to_log(sys_call_error(SERVER, "accept"));
return FAILURE;
}
return caller;
}
int establish_connection(sockaddr_in& connection_info)
{
// Create socket
if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) < SUCCESS)
{
server_log->write_to_log(sys_call_error(SERVER, "socket"));
return FAILURE;
}
// Bind `sock` with given addresses
if (bind(server_sock, (struct sockaddr *) &connection_info, \
sizeof(struct sockaddr_in)) < SUCCESS)
{
close(server_sock);
server_log->write_to_log(sys_call_error(SERVER, "bind"));
return FAILURE;
}
// Max # of queued connects
if (listen(server_sock, MAX_PENDING_CONNECTIONS) < SUCCESS)
{
server_log->write_to_log(sys_call_error(SERVER, "listen"));
return FAILURE;
}
// Create a set of file descriptors and empty it.
fd_set set;
bool is_inside;
int ret_val;
while(true)
{
FD_ZERO(&set);
FD_SET(STDIN_FILENO, &set);
FD_SET(server_sock, &set);
struct timeval tv = {2, 0};
ret_val = select(server_sock + 1, &set, NULL, NULL, &tv); // TODO ret_val
is_inside = FD_ISSET(STDIN_FILENO, &set);
if(is_inside)
{
// get user input
string user_input;
getline(cin, user_input);
if ((strcasecmp(user_input.c_str(), EXIT_TEXT) == 0))
{
return SUCCESS;
}
}
is_inside = FD_ISSET(server_sock, &set);
if(is_inside)
{
// get the first connection request
int current_connection = get_ready_connection(server_sock);
if (current_connection == FAILURE) {
free_allocated_memory();
exit_write_close(server_log, sys_call_error(SERVER, "accept"),
ERROR);
}
// if exit was not typed by the server's stdin, process the request
pthread_t thread;
// create thread
if (pthread_create(&thread, NULL, command_thread_func, ¤t_connection) != 0)
{
free_allocated_memory();
exit_write_close(server_log, sys_call_error(SERVER, "pthread_create"), ERROR);
}
}
}
}
All im trying to do, is to "listen" to STDIN for the user to type 'EXIT' in server's shell, and to wait for clients to pass commands from their shells (every time a command is recieved by the server from the user, the server parses it, and the server creates a thread that handles execution of the command)
To do it simultaniously, i used select().
When i work with a single thread, everything's perfect. But the problem is when im connecting another client i get a seg fault. i suspect that the problem is right here. any suggestions?
Hard to know if this is your exact problem, but this is definitely a problem:
You can't call pthread_create and provide a pointer to a stack variable (¤t_connection) as your thread function's argument. For one thing, it's subject to immediate destruction as soon as the parent exits that scope.
Secondly, it will be overwritten on the next call to get_ready_connection.
I am working on a Qt GUI that will handle a single client. I am NOT using the Qt TCP libraries or the Qt thread library. I am creating my own Server class (more or less for the experience/learning).
I wanted to make sure what I am doing with the pthread handler isn't going to come back to haunt me in the future. My question is... Is it bad practice to pass this into the pthread_create function? Could this cause problems? It seems to work ok but I am always weary about problems lurking when working with threads.
I will be happy to share more code if it is needed. Thanks for taking a look.
Server.hpp
class Server : public Socket{
public:
....
TCPSocket *accept() throw(SocketException);
static void *listen_for_clients(void *);
void start() throw(SocketException);
void set_listen() throw(SocketException);
private:
pthread_t listen_thread;
};
Server.cpp
void HandleTCPClient(TCPSocket *sock);
TCPSocket *Server::accept() throw(SocketException)
{
int new_conn_sd;
if ( (new_conn_sd = ::accept(socket_descriptor, NULL, 0)) < 0)
{
throw SocketException("Server: accept failed", true);
}
return new TCPSocket(new_conn_sd);
}
void *Server::listen_for_clients(void *ptr)
{
Server * p = (Server *)ptr;
p->set_listen();
for (;;)
{
HandleTCPClient(p->accept());
}
return 0;
}
void Server::start() throw(SocketException)
{
if(pthread_create(&listen_thread, NULL, listen_for_clients, this)) {
throw SocketException("Server: cannot create listen thread", true);
}
}
void Server::set_listen() throw(SocketException)
{
if (listen(socket_descriptor, queue_length) < 0)
{
throw SocketException("Server: set listening socket failed", true);
}
}
void HandleTCPClient(TCPSocket *sock) {
std::cout << "Handling client ";
.....
delete sock;
}