How can i accept RakNet Connecting request in c++? - c++

I want accept client's connecting request but i don't know how can i do this.
Serverside :
enum GameMessages
{
ID_GAME_MESSAGE_1 = ID_USER_PACKET_ENUM + 1
};
using namespace std;
int main(void)
{
RakNet::RakPeerInterface *peer = RakNet::RakPeerInterface::GetInstance();
bool isServer;
RakNet::Packet *packet;
RakNet::SocketDescriptor sd(SERVER_PORT, 0);
peer->Startup(MAX_CLIENTS, &sd, 1);
isServer = true;
if (isServer)
{
printf("Sunucu baslatiliyor.\n");
// We need to let the server accept incoming connections from the clients
peer->SetMaximumIncomingConnections(MAX_CLIENTS);
}
while (1)
{
for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive())
{
switch (packet->data[0])
{
case ID_REMOTE_DISCONNECTION_NOTIFICATION:
printf("Another client has disconnected.\n");
break;
case ID_REMOTE_CONNECTION_LOST:
printf("Another client has lost the connection.\n");
break;
case ID_REMOTE_NEW_INCOMING_CONNECTION:
printf("Another client has connected.\n");
break;
case ID_CONNECTION_REQUEST_ACCEPTED:
{
printf("Our connection request has been accepted.\n");
// Use a BitStream to write a custom user message
// Bitstreams are easier to use than sending casted structures, and handle endian swapping automatically
RakNet::BitStream bsOut;
bsOut.Write((RakNet::MessageID)ID_GAME_MESSAGE_1);
bsOut.Write("Oyuna hosgeldin emmolu.");
peer->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, packet->systemAddress, false);
}
break;
case ID_NEW_INCOMING_CONNECTION:
printf("Bir baglanti geliyor.\n");
break;
case ID_NO_FREE_INCOMING_CONNECTIONS:
printf("The server is full.\n");
break;
case ID_DISCONNECTION_NOTIFICATION:
if (isServer) {
printf("A client has disconnected.\n");
}
else {
printf("We have been disconnected.\n");
}
break;
case ID_CONNECTION_LOST:
if (isServer) {
printf("A client lost the connection.\n");
}
else {
printf("Connection lost.\n");
}
break;
case ID_GAME_MESSAGE_1:
{
RakNet::RakString rs;
RakNet::BitStream bsIn(packet->data, packet->length, false);
bsIn.IgnoreBytes(sizeof(RakNet::MessageID));
bsIn.Read(rs);
printf("%s\n", rs.C_String());
}
break;
default:
printf("Message with identifier %i has arrived.\n", packet->data[0]);
break;
}
}
}
RakNet::RakPeerInterface::DestroyInstance(peer);
return 0;
}
When i try my work it's giving me .
[LOG]
Server : Server started.
Client : Sent request to connect server.
Server : A request received from client to connect server.
Server : Accept client's request. ( What i'm trying to do )

Related

grpc++: process hang by synchronous stub call , set_deadline not valid?

i ran into a problem , pls help:
What version of gRPC and what language are you using?
libgrpc++.so.1.26.0
What operating system (Linux, Windows,...) and version?
centos7
What did you do?
my scenario is : I have a grpc server named A and, when I receive a grpc message, send the message to another grpc server named B directly;
my server A initial(CRpcNetServer class):
int CRpcNetServer::Initialize()
{
std::string listenAddr = "this is listen address";
ServerBuilder builder;
builder.AddListeningPort(listenAddr, grpc::InsecureServerCredentials());
//register
builder.RegisterService(&AService_); //protobuf definition A
builder.RegisterService(&BService_); //protobuf definition A
//
cq_ = builder.AddCompletionQueue();
server_ = builder.BuildAndStart();
new CallData(&AService_, &BService_, cq_.get(), CallData::S_TYPE_GRPC_MESSAGE);
//new CallData(&AService_, &BService_, cq_.get(), {other message type});
return ERROR_CODE_SUCCESS;
}
void CRpcNetServer::handleRpcs()
{
void *tag;
bool ok;
while (true)
{
if (GPR_UNLIKELY(!(cq_->Next(&tag, &ok))))
{
spdlog::error("handleRpcs||get next message failed, try again");
continue;
}
if (GPR_UNLIKELY(!ok))
{
spdlog::error("handleRpcs||get next message notok, try again");
continue;
}
static_cast<CallData *>(tag)->process();
}
}
when message arrived(CallData class):
void CallData::process()
{
if (status_ == CREATE)
{
status_ = PROCESS;
switch (s_type_)
{
case S_TYPE_GRPC_MESSAGE:
BService_->RequestOnMessage(&ctx_, &GrpcUpLinkMessage, &processGrpcUplinkResponse, cq_, cq_, this);
//case other message type
default:
break;
}
}
else if (status_ == PROCESS)
{
status_ = FINISH;
new CallData(AService_, BService_, cq_, this->s_type_);
switch (s_type_)
{
case S_TYPE_GRPC_UPLINK_MESSAGE:
{
Status ret = this->onGrpcUplinkMessage(gRPCUpLinkMessage, emptyResponse_);
processGrpcUplinkResponse.Finish(emptyResponse_, ret, this);
}
break;
default:
break;
}
}
else
{
GPR_ASSERT(status_ == FINISH);
delete this;
}
}
when i received a grpc message, send it to another grpc server directly:
//init grpc client:
CRpcNetClient::CRpcNetClient(){
std::shared_ptr<Channel> channel = grpc::CreateChannel({B server address}, grpc::InsecureChannelCredentials());
stub_ = BServerApi::SendToBDownlinkService::NewStub(channel);
}
//send
std::chrono::time_point<std::chrono::system_clock> deadline = std::chrono::system_clock::now() + std::chrono::milliseconds(100);
ClientContext context;
context.set_deadline(deadline);
std::time_t timestamp = getTimestamp();
Status status = stub_->publishMessage(&context, downLinkGroupRequest, &downLinkGroupResponse);
// process will hang here
std::chrono::time_pointstd::chrono::system_clock deadline = std::chrono::system_clock::now() + std::chrono::milliseconds(100);
I tried to set milliseconds to 1ms, it will return failed , so I think the param is worked, but while set it to 100, it will occurs some time (not inevitable).

MFC C++ : IcmpSendEcho returns successfully, but status is IP_DEST_HOST_UNREACHABLE and RoundTripTime is not the default timeout time

I use IcmpSendEcho inside my program to check if a specific pc corresponding to an IP address inside my internal network is on. This solution works effectively for almost all of our customers, but one of them has a very inusual case.
I certainly know that this specific computer (it happens with more than one computer, by the way) is on and operative 24/7, but the IcmpSendEcho behavior changes during the day and I don't understand why.
During the time slot 05:00 AM - 08:00 PM, IcmpSendEcho on this computer returns a successful echo request (IP_SUCCESS) with a plausible roundtrip time, but during the time slot 08:00 PM - 05:00 AM, IcmpSendEcho returns the error IP_DEST_HOST_UNREACHABLE. The strange part about this is that the roundtrip time DOES NOT correspond with the timeout time assigned to the IcmpSendEcho function, but is lower.
If i execute the test on a computer that is switched off, my code tells me that IcmpSendEcho request has failed, so the code goes to a different instruction block.
Why is this happening? What is the difference between the IcmpSendEcho request failing and succeeding but with an error code like IP_DEST_HOST_UNREACHABLE ?
Thank you for your help.
unsigned long ipaddr = inet_addr(CT2CA(myIpAddress));
HANDLE hIcmpFile;
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE) {
printf("\tUnable to open handle.\n");
printf("IcmpCreatefile returned error: %ld\n", GetLastError());
EDMLog::Error(_T("Unable to open handle. error code 001"));
errorCode = _T("001");
}
else {
char SendData[100];
for (int x = 0; x < 100; ++x) {
SendData[x] = 'A';
}
LPVOID ReplyBuffer = NULL;
DWORD ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*)malloc(ReplySize);
if (ReplyBuffer == NULL) {
printf("\tUnable to allocate memory\n");
EDMLog::Error(_T("Unable to allocate memory. error code 001"));
errorCode = _T("001");
}
else {
DWORD dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData),
NULL, ReplyBuffer, ReplySize, 10000);
printf("\tSent icmp message to %s\n", CT2CA(myIpAddress);
EDMLog::Information(_T("Test su indirizzo ") + myIpAddress);
if (dwRetVal != 0) {
/////////////////////////////////////
//HERE THE REQUEST IS SUCCESSFULL BUT THE ERROR CODE IS IP_DEST_HOST_UNREACHABLE
/////////////////////////////////////
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
if (dwRetVal > 1) {
printf("\tReceived %ld icmp message responses\n", dwRetVal);
printf("\tInformation from the first response:\n");
}
else {
printf("\tReceived %ld icmp message response\n", dwRetVal);
printf("\tInformation from this response:\n");
}
printf("\t Received from %s\n", inet_ntoa(ReplyAddr));
printf("\t Status = %ld\n",
pEchoReply->Status);
switch (pEchoReply->Status) {
case IP_SUCCESS:
//GESTIONE PARTICOLARE PER GAROM
//errorCode.Format(_T("90%d"), i + 1);
//GESTIONE TRADIZIONALE
errorCode = _T("000");
EDMLog::Debug(_T("Test eseguito correttamente."));
break;
case IP_BUF_TOO_SMALL:
EDMLog::Error(_T("Buffer too small. error code 101"));
errorCode = _T("101");
break;
case IP_DEST_NET_UNREACHABLE:
EDMLog::Error(_T("DEST NET UNREACHABLE. error code 102"));
errorCode = _T("102");
break;
case IP_DEST_HOST_UNREACHABLE:
EDMLog::Error(_T("DEST HOST UNREACHABLE. error code 103"));
errorCode = _T("103");
break;
case IP_DEST_PROT_UNREACHABLE:
EDMLog::Error(_T("DEST PROT UNREACHABLE. error code 104"));
errorCode = _T("104");
break;
case IP_DEST_PORT_UNREACHABLE:
EDMLog::Error(_T("DEST PORT UNREACHABLE. error code 105"));
errorCode = _T("105");
break;
case IP_NO_RESOURCES:
EDMLog::Error(_T("IP NO RESOURCES. error code 106"));
errorCode = _T("106");
break;
case IP_BAD_OPTION:
EDMLog::Error(_T("IP BAD OPTION. error code 107"));
errorCode = _T("107");
break;
case IP_HW_ERROR:
EDMLog::Error(_T("IP HW ERROR. error code 108"));
errorCode = _T("108");
break;
case IP_PACKET_TOO_BIG:
EDMLog::Error(_T("IP PACKET TOO BIG. error code 109"));
errorCode = _T("109");
break;
case IP_REQ_TIMED_OUT:
EDMLog::Error(_T("IP REQ TIMED OUT. error code 110"));
errorCode = _T("110");
break;
case IP_BAD_REQ:
EDMLog::Error(_T("IP BAD REQ. error code 111"));
errorCode = _T("111");
break;
case IP_BAD_ROUTE:
EDMLog::Error(_T("IP BAD ROUTE. error code 112"));
errorCode = _T("112");
break;
case IP_TTL_EXPIRED_TRANSIT:
EDMLog::Error(_T("IP TTL EXPIRED TRANSIT. error code 113"));
errorCode = _T("113");
break;
case IP_TTL_EXPIRED_REASSEM:
EDMLog::Error(_T("IP TTL EXPIRED REASSEM. error code 114"));
errorCode = _T("114");
break;
case IP_PARAM_PROBLEM:
EDMLog::Error(_T("IP PARAM PROBLEM. error code 115"));
errorCode = _T("115");
break;
case IP_SOURCE_QUENCH:
EDMLog::Error(_T("IP SOURCE QUENCH. error code 116"));
errorCode = _T("116");
break;
case IP_OPTION_TOO_BIG:
EDMLog::Error(_T("IP OPTION TOO BIG. error code 117"));
errorCode = _T("117");
break;
case IP_BAD_DESTINATION:
EDMLog::Error(_T("IP BAD DESTINATION. error code 118"));
errorCode = _T("118");
break;
case IP_GENERAL_FAILURE:
EDMLog::Error(_T("IP GENERAL FAILURE. error code 150"));
errorCode = _T("150");
break;
}
printf("\t Roundtrip time = %ld milliseconds\n",
pEchoReply->RoundTripTime);
if ((int)(pEchoReply->RoundTripTime) == 0)
valore.Format(_T("%d"), 1);
else
valore.Format(_T("%d"),(int)(pEchoReply->RoundTripTime));
}
else {
/////////////////////////////////////
//HERE THE REQUEST IS NOT SUCCESSFUL (TIMEOUT)
/////////////////////////////////////
printf("\tCall to IcmpSendEcho failed.\n");
DWORD lastError = GetLastError();
printf("\tIcmpSendEcho returned error: %ld\n", lastError);
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
if (dwRetVal > 1) {
printf("\tReceived %ld icmp message responses\n", dwRetVal);
printf("\tInformation from the first response:\n");
}
else {
printf("\tReceived %ld icmp message response\n", dwRetVal);
printf("\tInformation from this response:\n");
}
printf("\t Received from %s\n", inet_ntoa(ReplyAddr));
printf("\t Status = %ld\n",
pEchoReply->Status);
valore = _T("0");
switch (pEchoReply->Status) {
case IP_SUCCESS:
errorCode = _T("000");
EDMLog::Information(_T("Test eseguito correttamente."));
break;
case IP_BUF_TOO_SMALL:
EDMLog::Error(_T("Buffer too small. error code 101"));
errorCode = _T("101");
break;
case IP_DEST_NET_UNREACHABLE:
EDMLog::Error(_T("DEST NET UNREACHABLE. error code 102"));
errorCode = _T("102");
break;
case IP_DEST_HOST_UNREACHABLE:
EDMLog::Error(_T("DEST HOST UNREACHABLE. error code 103"));
errorCode = _T("103");
break;
case IP_DEST_PROT_UNREACHABLE:
EDMLog::Error(_T("DEST PROT UNREACHABLE. error code 104"));
errorCode = _T("104");
break;
case IP_DEST_PORT_UNREACHABLE:
EDMLog::Error(_T("DEST PORT UNREACHABLE. error code 105"));
errorCode = _T("105");
break;
case IP_NO_RESOURCES:
EDMLog::Error(_T("IP NO RESOURCES. error code 106"));
errorCode = _T("106");
break;
case IP_BAD_OPTION:
EDMLog::Error(_T("IP BAD OPTION. error code 107"));
errorCode = _T("107");
break;
case IP_HW_ERROR:
EDMLog::Error(_T("IP HW ERROR. error code 108"));
errorCode = _T("108");
break;
case IP_PACKET_TOO_BIG:
EDMLog::Error(_T("IP PACKET TOO BIG. error code 109"));
errorCode = _T("109");
break;
case IP_REQ_TIMED_OUT:
EDMLog::Error(_T("IP REQ TIMED OUT. error code 110"));
errorCode = _T("004");
valore = _T("10000");
break;
case IP_BAD_REQ:
EDMLog::Error(_T("IP BAD REQ. error code 111"));
errorCode = _T("111");
break;
case IP_BAD_ROUTE:
EDMLog::Error(_T("IP BAD ROUTE. error code 112"));
errorCode = _T("112");
break;
case IP_TTL_EXPIRED_TRANSIT:
EDMLog::Error(_T("IP TTL EXPIRED TRANSIT. error code 113"));
errorCode = _T("113");
break;
case IP_TTL_EXPIRED_REASSEM:
EDMLog::Error(_T("IP TTL EXPIRED REASSEM. error code 114"));
errorCode = _T("114");
break;
case IP_PARAM_PROBLEM:
EDMLog::Error(_T("IP PARAM PROBLEM. error code 115"));
errorCode = _T("115");
break;
case IP_SOURCE_QUENCH:
EDMLog::Error(_T("IP SOURCE QUENCH. error code 116"));
errorCode = _T("116");
break;
case IP_OPTION_TOO_BIG:
EDMLog::Error(_T("IP OPTION TOO BIG. error code 117"));
errorCode = _T("117");
break;
case IP_BAD_DESTINATION:
EDMLog::Error(_T("IP BAD DESTINATION. error code 118"));
errorCode = _T("118");
break;
case IP_GENERAL_FAILURE:
EDMLog::Error(_T("IP GENERAL FAILURE. error code 150"));
errorCode = _T("150");
break;
}
}
IcmpCloseHandle(hIcmpFile);
}
}
Obviously, any improvement of the above code is well received, thank you again.
The problem is how the address is resolved. For the case where the PC is in the same LAN, it is necessary to obtain the MAC address based on the destination IP address. It uses ARP protocol that cannot obtain the MAC address so it cannot send the ICMP message. Then it will probably respect the timeout. It will give up at timeout. In the other case, if you are sending an echo request ICMP message to a node that is outside the LAN, that message will be routed through intermediate routers (could be a gateway too). So the IP packet, conveying the ICMP message, will leave your PC to the next hop, somewhere beyond the next hop, a router will realize if cannot route that ICMP packet and it will return the ICMP message DestinationUnreachable to the origin node (your PC). When ping receives this message it doesn't make sense to wait for the timeout, it already received a message telling it the destination is unreachable.
Gotcha. The router had a rule that blocked any kind of traffic from an hour to an other hour. Obviously, the customer didn't tell me about it. Thank you all!

How to set timeout on socket receive vc++ mfc

I have created a server in MFC. Client is connected to server and server is waiting for receiving data, which is sent by the client.
I want a timeout period for receiving pSocket.Receive(cbuf,1).
Here is my code :
int i_userid; AfxSocketInit(); bool bRun = true;
CWinThread *pCurrentThread; pCurrentThread = AfxGetThread();
SOCKET pCurrentHandle; CSocket pSocket; pCurrentHandle =hClinetHandle;
pSocket.Attach(hClinetHandle);
LeaveCriticalSection(&m_socket_lock); CSocket t_socket;
CString m_Ipadd=L""; UINT m_portno=0;
pSocket.GetPeerName(m_Ipadd,m_portno);
st_Client* m_st_Client=new st_Client();
//receive Use Id and Get UserPortfolio CString m_token=L"";
CString New_data=L"";char cbuf[24];
for(int i=0;i<24;i++)
cbuf[i] ='\0';
while(bRun)
{
if(pSocket.Receive(cbuf,1)>0)
{
New_data=cbuf;
if(wcscmp(New_data,L"\r")==0 ||wcscmp(New_data,L"|")==0)
{
break;
}
m_token=m_token+New_data;
}
else
{
bRun=false;
break;
}
}
some other code of CTimeout but it didn't work there.........
void CServerSocket::OnAccept(int nErrorCode)
{
m_Client.m_hSocket = INVALID_SOCKET;
AfxMessageBox("Client Request Connection");
if(!SetTimeOut(10000))
{
ASSERT(FALSE);
// Error Handling...for some reason, we could not setup
// the timer.
}
if(!Accept(m_Client))
{
int nError = GetLastError();
if(nError==WSAEINTR)
AfxMessageBox("No Connections Arrived For 10 Seconds");
else
; // Do other error processing.
}
CSocket::OnAccept(nErrorCode);
}

I have used WaitForSingleObject in C++ and its return value is "WAIT_OBJECT_0" all the time

The function WaitForSingleObject returns timeout flag("WAIT_OBJECT_0") in all cases.
Only for testing I have commented this line
(while((WaitForSingleObject(ovread.hEvent,timeout)==WAIT_OBJECT_0)))
and the comport responds as expected.
I have tried various timeouts including INFINITE.
Can someone tell me where the error could be occurring.
int timeout=500;
OVERLAPPED ovread;
memset(&ovread, 0, sizeof(ovread));
ovread.hEvent = CreateEvent( 0,true,0,0);
while((WaitForSingleObject(ovread.hEvent,timeout)==WAIT_OBJECT_0))
{
//Execute the following code
ReadFile(h,buf,sizeof(buf),&read,&ovread);
}
The reading logic should more or less use the following code flow:
int timeout = 500;
OVERLAPPED ovread = {0}
ovread.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (ovread.hEvent == NULL) {
// Error creating overlapped event; abort.
return FALSE;
}
if (!ReadFile(h, buf, sizeof(buf), &read, &ovread)) {
if (GetLastError() != ERROR_IO_PENDING) {
// Handle error in communications
}
else {
DWORD ret = WaitForSingleObject(ovread.hEvent,timeout);
switch (ret) {
case WAIT_OBJECT_0:
HandleASuccessfulRead(buf, read);
break;
case WAIT_TIMEOUT:
// Handle timeout
break;
case WAIT_FAILED:
// Handle failure
break;
default:
// what else to handle?
break;
}
}
}
else {
// read completed immediately
HandleASuccessfulRead(buf, read);
}

SSL_accept takes 200ms (c / openssl)

Is it normal that SSL_accept(ssl) takes 200 ms?
Running as a windows service, written in c++, using MFC and Boost. Running on an intel xeon e5620 2.4G, with 4GB memory, and Win 7 Pro.
Following is my code. I meanwhile suspected that maybe other methods before SSL_accept (SSL_CTX_* RAND_* etc) might consume long time , but I logged everthing and discovered that SSL_accept is eating all the time.
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
{
return preverify_ok;
}
void somemethod() {
SSL *ssl = 0;
SSL_CTX *tlsctx = 0;
int ret_conn = -1;
tlsctx = SSL_CTX_new( SSLv23_method());
SSL_CTX_use_certificate_file(tlsctx, sCert , SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(tlsctx, sKey , SSL_FILETYPE_PEM);
RAND_write_file(sRandomPem);
int _rand_loaded = RAND_load_file(sRandomPem, -1 );
if(! SSL_CTX_load_verify_locations(tlsctx, sCACert, NULL))
{
// TODO // /* Handle error here */
}
SSL_CTX_set_verify( tlsctx, SSL_VERIFY_PEER, verify_callback );
ssl = SSL_new(tlsctx);
int _error = SSL_ERROR_WANT_READ;
int loopCount = 0;
// START MEASURING TIME FROM HERE
SSL_set_fd(ssl, _sck);
while(ret_conn != 1 )
{
loopCount++;
ret_conn = SSL_accept(ssl);
_error = SSL_get_error(ssl, ret_conn);
switch (_error)
{
case SSL_ERROR_NONE:
break;
case SSL_ERROR_WANT_WRITE:
break;
case SSL_ERROR_WANT_READ:
break;
case SSL_ERROR_WANT_X509_LOOKUP:
break;
case SSL_ERROR_SYSCALL:
break;
case SSL_ERROR_SSL:
break;
case SSL_ERROR_ZERO_RETURN:
break;
}
if( _error == SSL_ERROR_WANT_READ || _error == SSL_ERROR_WANT_WRITE)
{
Sleep(1);
} else
{
break;
}
}
if( ret_conn < 1)
{
Log("SSL_accept -1 ", ERR_error_string(_error, NULL));
return;
}
// MEASURING END HERE, takes ~200ms (on successfully accepting connection)
}
To my knowledge, SSL_accept is a blocking function, which waits for your client to connect. If your client connect 200 ms later than the beginning for the SSL_accept call, then you will measure that waiting time.