how can convert delivered string to char* linux c++ socket programming [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 10 days ago.
Improve this question
This is socket receive code
char buffer[1024];
int bytes_received;
string received_text;
const char* searchid;
bytes_received = recv(client_socket, buffer, sizeof(buffer), 0);
received_text.assign(buffer, bytes_received);
cout << "Received: " << received_text << endl;
searchid = received_text.c_str();
cout << "Received: " << searchid << endl;
The above code receive "test" and print this
Received: test
Received: t
Seeing that the code below works well, it seems that the problem is saving the value exchanged from the socket, but I can't find a way to solve the problem.
char buffer[1024];
int bytes_received;
string received_text;
const char* searchid;
bytes_received = "test";
cout << "Received: " << received_text << endl;
searchid = received_text.c_str();
cout << "Received: " << searchid << endl;
Received: test
Received: test
I need some help.
edit sending code
byte[] data = Encoding.Unicode.GetBytes(LoginID);
socket.Send(data, data.Length, SocketFlags.None);
LoginID is the input value to be sent to the server

Oh... thank you guys
The problem was with the client, not the server
wrong code
byte[] data = Encoding.Unicode.GetBytes(LoginID);
right code
byte[] data = Encoding.UTF8.GetBytes(LoginID);

Related

Reading Flatbuffers objects sent via ZMQ in C++ throws unhandled exception

I am trying to send a reasonably big Flatbuffers object over the network via ZMQ and then read it using C++. When accessing the object, I get unhandled exceptions that I don't know how to solve. Even this minimal example fails:
The flatbuffers schema:
namespace flatbuffer;
table TestBuf {
testStatus:bool;
testNumber:double;
testInt:int;
}
root_type TestBuf;
The main.cpp using the REP socket:
int main() {
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REP);
socket.bind("tcp://*:5555");
std::cout << "Listening for requests." << std::endl;
std::cout << "-----" << std::endl;
double count = 0;
while (1) {
zmq::message_t request;
socket.recv(&request);
// Read incoming data
auto reqmsg = flatbuffer::GetTestBuf(&request);
std::cout << "Received: " << reqmsg << std::endl;
flatbuffers::FlatBufferBuilder fbb;
flatbuffer::TestBufBuilder builder(fbb);
count++;
builder.add_testNumber(count);
std::cout << "Sending " << count << std::endl;
auto response = builder.Finish();
fbb.Finish(response);
// Send the flatbuffer
int buffersize = fbb.GetSize();
zmq::message_t message(buffersize);
memcpy((void *)message.data(), fbb.GetBufferPointer(), buffersize);
socket.send(message);
}
return 0;
}
The main.cpp using the REQ socket:
int main() {
// Prepare ZMQ context and socket
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REQ);
std::cout << "Sending out data requests." << std::endl;
socket.connect("tcp://localhost:5555");
double count = 0;
while (1) {
// Formulate response
flatbuffers::FlatBufferBuilder fbb;
flatbuffer::TestBufBuilder builder(fbb);
count++;
builder.add_testNumber(count);
auto response = builder.Finish();
fbb.Finish(response);
// Send the flatbuffer
std::cout << "Sending. " << count << ". ";
int buffersize = fbb.GetSize();
zmq::message_t message(buffersize);
memcpy((void *)message.data(), fbb.GetBufferPointer(), buffersize);
socket.send(message);
std::cout << "Sent. ";
// Receive reply
zmq::message_t reply;
socket.recv(&reply);
// Read the data
auto inmsg = flatbuffer::GetTestBuf(&reply);
std::cout << " Received reply: " << inmsg << std::endl;
//auto num = inmsg->testNumber();
//std::cout << num << " test number.";
}
return 0;
}
This code runs fine and displays (I think) the raw buffer each program is receiving. Strangely, it is not changing, although the content of the message should be. If I uncomment the last two lines and try to access inmsg->testNumber(), I get this error message:
Unhandled exception at 0x000000013F373C53 in KUKAREQ.exe: 0xC0000005: Access violation reading location 0x00000000004B35D8.
I have sent Flatbuffers objects through ZMQ successfully before, but I have not read them in C++. I am fairly sure I followed the Flatbuffers tutorial closely, but something is obviously going wrong. Pointers? Buffer sizes? Either way I would appreciate help.
Edit: To clarify my comment on the accepted answer, the offending line was:
auto inmsg = flatbuffer::GetTestBuf(&reply);
It has to be changed to:
auto inmsg = flatbuffer::GetTestBuf(reply.data());
Whoever reads this question may also be interested to know that I later came across a bug which occurs when the FlatBufferBuilder functions are not called in the correct order. Apparently the order in which the Flatbuffers object is built is important. Finding that one took me a while - novices watch out.
Not familiar with ZeroMQ, but flatbuffer::GetTestBuf(&request) this looks problematic.. you need to pass the buffer, not the message structure. Likely request.data() or similar works better.
In general, if it crashes in FlatBuffers, you should use the verifier to verify the buffer you're passing to FlatBuffers. If that fails, it means you're not passing legal data to FlatBuffers, as is the case here.
Also, you may want to check if ZeroMQ can send buffers without copying, will be faster.

Recv always receive 1 less byte

I'm really tired with this - I tried to fix it for about 5 hours and I still can't semm to find a problem, maybe You guys can.
My problem is that recv at the client side always recv one less byte when I'm sending IP from server. And server is always sending the right ammount of data and right data and IP adress on client side always come without 1 number and it's always the first one so server send:
192.168.0.101
Client receive:
92.168.0.101
What is also important is that client's name is always received without any problems - it only happens with IP adress.
Take a closer look at that:
Server side sending data [2 strings - first is name of client and second is his IP adress]:
j is iterator of list to loop thourght all clients and client variable is the one which is asking for all client's data
std::cout << j->client_name << " ";
int lenght = j->client_name.length()+1 ; //+1 for '\0' byte at the client buffer
std::cout << "Lenght (+1): " << lenght << " ";
lenght = htonl(lenght); //change byte order to network
send(client->client_socket,(char*)&lenght,sizeof(int),0);
std::cout << "I have sent: " << send(client->client_socket,j->client_name.c_str(),j->client_name.length(),0) << std::endl;
std::cout << inet_ntoa(j->client_connection.sin_addr) << " "; //showing IP adress
unsigned lenght2 = strlen(inet_ntoa(j->client_connection.sin_addr))+1; //+1 for '\0' byte at the client buffer
std::cout << "Lenght (+1): " << lenght2 << " ";
unsigned realistic_lenght = lenght2;
lenght2 = htonl(lenght2);
send(client->client_socket,(char*)&lenght,sizeof(unsigned),0);
std::cout << "I have sent: " << send(client->client_socket,inet_ntoa(j->client_connection.sin_addr),realistic_lenght,0) << std::endl;
And as I said on server side everything seems to be good and here's code to receive data on client side:
char* data_buffor;
int lenght = 0;
recv(data.client_socket,(char*)&lenght,sizeof(int),0);
lenght = ntohl(lenght);
std::cout << "I have received: " << lenght << std::endl;
data_buffor = new char[lenght];
if (data_buffor != NULL) std::cout << "ALLOCATION WAS SUCCESFULL" << std::endl;
std::cout << "I have received: " << recv(data.client_socket,data_buffor,lenght,0) << std::endl;
data_buffor[lenght-1] = '\0';
temp.client_name = data_buffor; // everything is fine here
delete data_buffor;
data_buffor = NULL;
unsigned lenght2 = 0;
recv(data.client_socket,(char*)&lenght2,sizeof(unsigned),0);
lenght2 = ntohl(lenght2);
std::cout << "I have received: " << lenght2 << std::endl; // I DONT KNOW WHY BUT HERE I GET CRAZY NUMBERS LIKE 3203 and I should get 14 with IP: 192.168.0.101 + one byte for '\0' I think that may be causing all problems but I have no idea how to fix it.
data_buffor = new char[lenght2];
if (data_buffor != NULL) std::cout << "ALLOCATION WAS SUCCESFULL" << std::endl;
std::cout << "I have received " << recv(data.client_socket,data_buffor,lenght2,0) << std::endl;
temp.client_ip_adress = data_buffor;
all_clients.push_back(temp);
delete data_buffor
data_buffor = NULL;
Any help would be highly appreciated.
When the server sends the client name, it is sending the length as the length of the string + 1 to include the terminating NULL character. However, the value returned by std::string::length() does NOT include the terminating NULL, so the server is not actually sending the terminating NULL to the client. When the client then reads the name, it reads the first character of the IP address as the terminating NULL of the name, but you never notice that because the client overwrites that byte in data_buffor with '\0' instead of relying on the server to send the '\0'.

why same output is returned when popn() is calling again and again [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I am trying below example
#include <boost/thread.hpp>
#include <boost/thread/condition.hpp>
#include <iostream>
#include <string>
#include <stdio.h>
std::string exec(char* cmd, boost::uint16_t *piOutVid, boost::uint16_t *piOutPid) {
boost::uint16_t uint_pid;
boost::uint16_t uint_vid = 0x05e0;
piOutVid = &uint_vid;
FILE* pipe1 = popen(cmd, "r");
if (!pipe1) return "ERROR";
char buffer[128];
unsigned int value;
std::string result = "";
while(!feof(pipe1)) {
if(fgets(buffer, 128, pipe1) != NULL)
if(strncpy(buffer, "1300", 4))
{
uint_pid = 0x1300;
std::cout << "value: " << buffer << std::endl;
}
else if(strncpy(buffer, "1900", 4))
{
uint_pid = 0x1900;
std::cout << "value: " << buffer << std::endl;
}
else if(strncpy(buffer, "0820", 4))
{
uint_pid = 0x0820;
std::cout << "value: " << buffer << std::endl;
}
result += buffer;
}
pclose(pipe1);
buffer[127] = '\0';
return result;
}
int main()
{
boost::uint16_t *piOutVid;
boost::uint16_t *piOutPid;
std::cout << "Boost threading..." << std::endl;
//boost::thread *nwThread = new boost::thread(boost::bind(class::method, this));
char *cmd = "lsusb|grep 'Symbol'|cut -d \":\" -f 3|cut -d \" \" -f 1";
exec(cmd, piOutVid, piOutPid);
}
when run this program first time. it worked correctly but reusing the program is not working properly. First time I test with a device (PID = 1300) then remove it and plug a new device (PID = 0820) and run the program again. But still give the same below output.
Boost threading...
value: 1300
Process returned 0 (0x0) execution time : 0.059 s
Press ENTER to continue.
pclose() returns 0
Your if statements are based on the result of a strncpy, which always returns the memory address of destination. So by definition, if the copy succeeds it's always going to return a value which evaluates to true. And thus always hit your 0x1300 block.
Did you mean to use strcmp?

Boost sockets - client is not receiving all bytes from server

I am developing an application with C++ and having some difficulty with boost sockets. The server sends an image but not all the bytes are received by the client; the client always receives about 500 bytes less than the server sent. Provided below is the pertinent code and screenshots of the program running.
Server code:
int sent = boost::asio::write(*socket, response, boost::asio::transfer_all(), error);
std::cout << "Sent: " << sent << std ::endl;
Client code (I know that read_some will block if the total bytes sent by the server is divisible by 10000; this code is just for testing):
int len = 0;
int count = 0;
do {
len = socket->read_some( boost::asio::buffer( imageData, 10000 ) );
count += len;
std::cout << "len: " << len << std::endl;
std::cout << "count: " << count << std::endl;
} while(len == 10000);
std::cout << "Image Received of size: " << count << std::endl;
Screenshot of server:
Screenshot of client:
Thanks for your time; any help or suggestions would be greatly appreciated.
There're no guarantee you'll receive complete buffers of 10000 bytes.
I'd recommend following approach:
To send some binary data w/o any explicit terminator, first send its size and only then data itself. In this case client will know how many data in this chunk it should receive.

Interpretation of homework requirements, involving client/server communication

I've been working on an assignment that asks us to implement some code provided to us that allows the creation of a server and client that can communicate. I was to fork a process in main, and then test the various request options available, and then measure the difference in time it took to do this via the child process, or locally using a function. I'm unsure if I've interpretated the requirements correctly though. On top of this, all the timing functions return 0 seconds. Not sure if this is correct or not. I'll post a small portion of the code.
Homework statement (only a small portion):
Measure the invocation delay of a request (i.e. the time between the
invocation of a request until the response comes back.) Compare that
with the time to submit the same request string to a function that
takes a request and returns a reply (as compared to a separate process
that does the same). Submit a report that compares the two.
The function declared before main:
string myfunc(string request){
//string myreq = request;
RequestChannel my_func_channel("control", RequestChannel::CLIENT_SIDE);
string reply1 = my_func_channel.send_request(request);
return reply1;
}
And how I interpreted the directions in code:
int main(int argc, char * argv[]) {
//time variables
time_t start, end;
double time_req_1, time_req_func;
cout << "client.C Starting...\n" << flush;
cout << "Forking new process...\n " << flush;
pid_t childpid = fork();
if(childpid == -1)
cout << "Failed to fork.\n" << flush;
else if(childpid == 0){
cout << "***Loading Dataserver...\n" << flush;
//Load dataserver
RequestChannel my_channel("control", RequestChannel::CLIENT_SIDE);
cout << "***Dataserver Loaded.\n" << flush;
time(&start);
string reply1 = my_channel.send_request("hello");
cout << "***Reply to request 'hello' is '" << reply1 << "'\n" << flush;
time(&end);
time_req_1 = difftime(end,start);
cout <<"\n\nRequest 1 took : "<< time_req_1 << flush;
}
else{//parent
time(&start);
string s = myfunc("hello");
time(&end);
time_req_func = difftime(end,start);
cout <<"\nmyfunc Request took: "<< time_req_func << "\n" << flush;
}
usleep(1000000);
}
This is an abbreviated version of my code, but contains everything you should need to figure out whats going on. Have I done what the directions stated? Also, is it likely that my 0 seconds results are correct?
The time it takes to do it once may be (probably is) too small to measure, so time how long it takes to do it many times and then work out how long each one took.