Sending and receiving structs using UDP (WinSock & C++)? - c++

I have two programs. I need one of them to send data and the other to receive that data.
I have some code in place that is hopefully sending a struct across the network.
However, I don't even know if it is working properly because I don't know how to code the receiving program to receive structs and pass the data it receives into a local struct to be manipulated.
Here is the code I'm using to send if it helps any
gamePacket.PplayerX = userSprite.x;
gamePacket.PplayerY = userSprite.y;
gamePacket.Plives = lives;
gamePacket.Pstate = state;
for(int z=0;z<8;z++)
{
gamePacket.PenemyX[z] = enemySprite[z].x;
gamePacket.PenemyY[z] = enemySprite[z].y;
}
char Buffer[sizeof(gamePacket)];
UDPSocket.Send(Buffer);
The struct is called Packet and gamePacket is an instance of it.
What I am stuck with is:
Is the code I posted even sending the struct
How do I receive the struct in the receiving program so that I can use the data inside it.

Its not send, you only declare a buffer. To send it you need to fill it. Also the way you use sizeof is wrong, it probably doesn't return the right size of all fields, you should count them up.
When you received everything you do the opposite, you allocate a struct and fill it using ofsets
If you need examples just ask. But learning is doing research so an push in the right direction is I think enough. (There are thousand examples on this.)
Ps: you can use pointers + offset because the memory of the struct is layed out next to each other. It are blocks of memory, just like an array.
EDIT; this link is what you need: Passing a structure through Sockets in C
EDIT: Example using pointers:
EDIT: Is this C# or C/C++? I'm sorry if so, change the example to C/C++ ;)
'
struct StructExample
{
int x;
int y;
};
int GetBytes(struct* Struct, void* buf)
{
//Access the memory location and store
*(int*)(buf + 0) = Struct->x;
*(int*)(buf + sizeof(int)) = Struct->y;
return sizeof(Struct->x) + sizeof(Struct->y)
}
Ps: I typed it with my mobile, I'm not 100% sure it compiles/works.

In c and c++ it is possible to use this code:
struct StructExample
{
int x;
int y;
};
struct StructExample a;
a->x = 1;
a->y = 2;
send(FSocket, &a, sizeof(a), 0);

Related

Passing array of stuct to kernel results in segfault on write?

Maybe I missed something from the tutorials because this is driving me nuts.
What I'm trying to accomplish: I want to create an array of structs for the OpenCL device to use as a work area. The host doesn't need to see it or interact with it in any way, it's just meant as a "scratch" space for the kernel to work within.
Here's what I have:
Declaration of struct inside header file accessible by both the main program and the OpenCL kernel:
typedef struct {
uint64_t a;
uint32_t b;
} result_list;
Initializing the scratch space buffer "outputBuffer" to hold MAX_SIZE elements:
cl_mem outputBuffer;
outputBuffer = clCreateBuffer(this->context,
CL_MEM_READ_WRITE,
sizeof(result_list) * MAX_SIZE,
NULL,
&status);
I never call clEnqueueWriteBuffer because the host doesn't care what the memory is. It's simply meant to be a working space for the kernel. I leave it as uninitialized but allocated.
Setting it as an argument for the kernel to use:
status = clSetKernelArg(myKernel,
1,
sizeof(cl_mem),
&this->outputBuffer);
The kernel (simplified to remove non-issue sections):
__kernel void kernelFunc(__global const uint32_t *input, __global result_list *outputBuffer) {
if (get_global_id(0) >= MAX_SIZE) { return; }
// Make a few local variables and play with them
outputBuffer[0].a = 1234; // Memory access violation here
// Code never reaches here
}
What am I doing wrong?
I installed CodeXL from AMD and it doesn't help much with debugging issues like these. The most it gives me is "The thread tried to read from or write to a virtual address to which it does not have access."
edit: It seems like it really doesn't like typedefs. Instead of using a struct, I simplified it to typedef uint64_t result_list and it refused to compile, saying "a value of type 'ulong' cannot be assigned to an entity of type 'result_list'", even though result_list -> uint64_t -> unsigned long.
Your problem is that you cannot put in a single header both definitions for HOST and DEVICE.
You have to separate them like this:
//HOST header
struct mystruct{
cl_ulong a;
cl_uint b;
};
//DEVICE header
typedef struct{
ulong a;
uint b;
} mystruct;
Notice that I also changed the datatype to the standar OpenCL datatypes. You should use those instead for compatibility.

Robust, simple (and fast) interprocess communication in C++ on Windows

I am developing a plug-in for two 3rd party programs: A and B in C++ on Windows (7) and need a robust, relatively simple (and fast) way to communicate between the two programs.
The communication is one way: based on user interaction in program A I want my plug-in inside program A to send a signal that ends up calling a function inside my plug-in in program B.
The protocol is simple. This is the signature of the receiving function inside my plug-in in B:
struct XYZ {
double x, y, z;
}
void polyLineSelected(long id, std::vector<XYZ> & points);
How would you recommend to do this?
By far the easiest way to implement one-way communication on Windows is to send a WM_COPYDATA message. It takes a COPYDATASTRUCT parameter to move arbitrary data from one application to another.
For your specific example an implementation of the sender would look like this:
// Declare symbolic constants to identify data
enum DataType {
DataType_Points
};
// Declare struct to hold compound data
struct IPCData {
long id;
XYZ pts[];
};
// Allocate buffer
const size_t bufferSize = offsetof(IPCData, pts[points.size()]);
vector<char> buffer(bufferSize);
IPCData* pData = reinterpret_cast<IPCData*>(&buffer[0]);
// Fill the buffer
pData->id = 42;
copy(points.begin(), points.end(), &pData->pts[0]);
// Prepare COPYDDATASTRUCT
COPYDATASTRUCT cds = { 0 };
cds.dwData = DataType_Points; // Can be used by the receiver to identify data
cds.cbData = bufferSize;
cds.lpData = pData;
// Send the data
SendMessage(hWndRecv, WM_COPYDATA,
(WPARAM)hWndSender,
(LPARAM)(LPVOID)&cds);

How can I create C-style structs in Clojure?

I am trying to create C-style structs in Clojure, so I can call a poorly documented C++ API from Clojure.
The API is designed to send and receive serialized protobuf messages (the good) preceded by a C Header struct (the bad). The initial handshake is an RPCHandshakeHeader struct and the process is roughly described in the code below:
struct RPCHandshakeHeader {
char magic[8];
int version;
static const char REQUEST_MAGIC[9];
static const char RESPONSE_MAGIC[9];
};
[...snip...]
const char RPCHandshakeHeader::REQUEST_MAGIC[9] = "FooBar?\n";
[...snip...]
RPCHandshakeHeader header;
memcpy(header.magic, RPCHandshakeHeader::REQUEST_MAGIC, sizeof(header.magic));
header.version = 1;
socket = new CActiveSocket();
socket->Initialize();
socket->Open((const uint8 *)"localhost", 5000);
socket->Send((uint8*)&header, sizeof(header));
[...code to read response...]
How can I do this in clojure? Do I need to use JNA/JNI?
Is there a way to create a C struct, turn it into binary and send it over a socket? (I think this is what I need to do)
Sounds like a job for gloss! I don't know the details of this part of the API, but you want to look particularly at compile-frame, and repeated for the character strings.

How to serialize an object to send over network

I'm trying to serialize objects to send over network through a socket using only STL. I'm not finding a way to keep objects' structure to be deserialized in the other host. I tried converting to string, to char* and I've spent a long time searching for tutorials on the internet and until now I have found nothing.
Is there a way to do it only with STL?
Are there any good tutorials?
I am almost trying boost, but if there is how to do it with STL I'd like to learn.
You can serialize with anything. All serialization means is that you are converting the object to bytes so that you can send it over a stream (like an std::ostream) and read it with another (like an std::istream). Just override operator <<(std::ostream&, const T&) and operator >>(std::istream&, T&) where T is each of your types. And all the types contained in your types.
However, you should probably just use an already-existing library (Boost is pretty nice). There are tons of things that a library like Boost does for you, like byte-ordering, taking care of common objects (like arrays and all the stuff from the standard library), providing a consistent means of performing serialization and tons of other stuff.
My first question will be: do you want serialization or messaging ?
It might seem stupid at first, since you asked for serialization, but then I have always distinguished the two terms.
Serialization is about taking a snapshot of your memory and restoring it later on. Each object is represented as a separate entity (though they might be composed)
Messaging is about sending information from one point to another. The message usually has its own grammar and may not reflect the organization of your Business Model.
Too often I've seen people using Serialization where Messaging should have been used. It does not mean that Serialization is useless, but it does mean that you should think ahead of times. It's quite difficult to alter the BOM once you have decided to serialize it, especially if you decide to relocate some part of information (move it from one object to another)... because how then are you going to decode the "old" serialized version ?
Now that that's been cleared up...
... I will recommend Google's Protocol Buffer.
You could perfectly rewrite your own using the STL, but you would end up doing work that has already been done, and unless you wish to learn from it, it's quite pointless.
One great thing about protobuf is that it's language agnostic in a way: ie you can generate the encoder/decoder of a given message for C++, Java or Python. The use of Python is nice for message injection (testing) or message decoding (to check the output of a logged message). It's not something that would come easy were you to use the STL.
Serializing C++ Objects over a Network Socket
This is 6 years late but I just recently had this problem and this was one of the threads that I came across in my search on how to serialize object through a network socket in C++. This solution uses just 2 or 3 lines of code. There are a lot of answers that I found work but the easiest that I found was to use reinterpret_cast<obj*>(target) to convert the class or structure into an array of characters and feed it through the socket. Here's an example.
Class to be serialized:
/* myclass.h */
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
public:
int A;
int B;
MyClass(){A=1;B=2;}
~MyClass(){}
};
#endif
Server Program:
/* server.cpp */
#include "myclass.h"
int main (int argc, char** argv)
{
// Open socket connection.
// ...
// Loop continuously until terminated.
while(1)
{
// Read serialized data from socket.
char buf[sizeof(MyClass)];
read(newsockfd,buf, sizeof(MyClass));
MyClass *msg = reinterpret_cast<MyClass*>(buf);
std::cout << "A = " << std::to_string(msg->A) << std::endl;
std::cout << "B = " << std::to_string(msg->B) << std::endl;
}
// Close socket connection.
// ...
return 0;
}
Client Program:
/* client.cpp */
#include "myClass.h"
int main(int argc, char *argv[])
{
// Open socket connection.
// ...
while(1)
{
printf("Please enter the message: ");
bzero(buffer,256);
fgets(buffer,255,stdin);
MyClass msg;
msg.A = 1;
msg.B = 2;
// Write serialized data to socket.
char* tmp = reinterpret_cast<char*>(&msg);
write(sockfd,tmp, sizeof(MyClass));
}
// Close socket connection.
// ...
return 0;
}
Compile both server.cpp and client.cpp using g++ with -std=c++11 as an option. You can then open two terminals and run both programs, however, start the server program before the client so that it has something to connect to.
Hope this helps.
I got it!
I used strinstream to serialize objects and I sent it as a message using the stringstream's method str() and so string's c_str().
Look.
class Object {
public:
int a;
string b;
void methodSample1 ();
void methosSample2 ();
friend ostream& operator<< (ostream& out, Object& object) {
out << object.a << " " << object.b; //The space (" ") is necessari for separete elements
return out;
}
friend istream& operator>> (istream& in, Object& object) {
in >> object.a;
in >> object.b;
return in;
}
};
/* Server side */
int main () {
Object o;
stringstream ss;
o.a = 1;
o.b = 2;
ss << o; //serialize
write (socket, ss.str().c_str(), 20); //send - the buffer size must be adjusted, it's a sample
}
/* Client side */
int main () {
Object o2;
stringstream ss2;
char buffer[20];
string temp;
read (socket, buffer, 20); //receive
temp.assign(buffer);
ss << temp;
ss >> o2; //unserialize
}
I'm not sure if is necessary convert to string before to serialize (ss << o), maybe is possible directly from char.
I think you should use google Protocol Buffers in your project.In network transport Protocol buffers have many advantages over XML for serializing structured data. Protocol buffers:
are simpler
are 3 to 10 times smaller
are 20 to 100 times faster
are less ambiguous
generate data access classes that are easier to use programmaticall
and so on. I think you need read https://developers.google.com/protocol-buffers/docs/overview about protobuf

Problem with reading data into structs using a C casting method

I'm writing an MD3 model loader in C++ and I understand the file format and what I need to do but I can't seem to get the syntax right. I have a class for the model and within that class there are a set of structs which will have the model data read into them. In the implementation of the class there is a constructor which reads data in when initialised with an MD3 file. I am using C style casting to do this. The first struct seems to be working and the data appears to be read in correctly but the following two seem to have all values left as zero which shouldn't be the case. The code compiles without error but I'm fairly new to C++ so I've probably made a simple mistake here!
The main file just set up the object with an MD3 file and then goes on to set up some OpenGL things but that's all working correctly and doesn't effect the constructor.
The interface:GameObject.h
class GameObject1 {
public:
GameObject1();
GameObject1(const char * filename);
virtual ~GameObject1();
virtual void Draw();
private:
struct md3_header_t
{
int IDENT; //id of file, always "IDP3"
int Version; //version number, always 15
char Name[64]; //name of character
int Flags; //blank but needed
int Num_frames; //number of Frames
int Num_surfaces; // number of shaders
int Num_skins; //...
int Num_triangles; //num triangles - important one
int Ofs_triangles; // offset of triangles
int Ofs_frames; // frames offset
int Ofs_tags; // tags offset
int Ofs_surfaces; //offset to surfaces
int Ofs_eof; //offset of end of header
};
typedef float vec3[3];
struct md3_frame_header_t
{
vec3 Min_bounds; //first corner of bounding box
vec3 Max_bounds; //other corner
vec3 local_origin; //usually 0 0 0
float Radius; //radius of bounding sphere
char NAME[16]; // name of frame
};
struct md3_tag_header_t
{
char NAME[64]; //name of tag
vec3 origin; //origin of tag eg head or torso
vec3 Axis[3]; //axis stuff
};
struct md3_surface_header_t
{
int IDENT; //id, must be IDP3
char Name[64]; //name of mesh
int Flags; // blank space
int Num_frames; // number of frames
int Num_shaders; // no shaders
int Num_vert; // number verts
int Num_triangles; //number of triangles
int Ofs_triangles; //offset of triangle data from surface start
int Ofs_shaders; // offset of shaders
int Ofs_st; // offset texture data
int Ofs_xyznormal; // offset of verts
int Ofs_end; // offset of end of surface section from start
};
and the interface GameObect.cpp, NOTE I've only included the constructor method here since the destructor and the draw method are both empty currently:
#include "GameObject1.h"
GameObject1::GameObject1() {
//if we have no model...
}
//constructor if a model has been provided
GameObject1::GameObject1(const char * filename) {
ifstream md3file;
md3file.open(filename, ios::in|ios::binary);
// C stuff
md3_header_t * md3header = (struct md3_header_t *)
malloc(sizeof(struct md3_header_t));
md3file.read((char *) md3header, sizeof (struct md3_header_t));
// Check the file
if (md3header->IDENT != 860898377) {
// Error!
cerr << "Error: bad version or identifier" << endl;
}
// seekg to search through the file to add new data to structs
// frame struct
md3_frame_header_t * md3frame = (struct md3_frame_header_t *)
malloc(sizeof(struct md3_frame_header_t));
md3file.seekg(md3header->Ofs_frames);
md3file.read((char *) md3frame, sizeof (struct md3_frame_header_t));
//surface struct
md3_surface_header_t * md3surface = (struct md3_surface_header_t *)
malloc(sizeof( md3_surface_header_t));
md3file.seekg(md3header->Ofs_surfaces);
md3file.read((char *) md3surface, sizeof (struct md3_surface_header_t));
md3file.close();
}
GameObject1::~GameObject1() {
// deconstructor
}
void GameObject1::Draw(){
// eventually a method to draw the model to screen using OpenGL and SDL
}
I'm really lost on this one so any help would be greatly appreciated.
Thanks,
Jon
Check the values of md3header->Ofs_frames and md3header->Ofs_surfaces to make sure they aren't trying to index past the end of the file. If they are, then the MD3 file may be corrupt or reading the file is not mapping properly to the struct.
Not sure if this is an issue but you may run into problems on 64 bit system if the the file was generated on a 32 bit (and vice versa) since the size of the ints would be different which would throw off the mapping to the struct.
May want to find a tool that you know can read the files properly and compare those values with the ones you are getting. Or use a hex editor to manually look through the file to verify the values.
Have a look at the memory layout of your structs: print out sizeof(float), sizeof(int), sizeof(char), sizeof(md3_frame_header_t), etc. and see if they are exactly what you expect. If not, you might want to play around with #pragma pack, to force the momory layout of your struct to be the file layout. Also, is the endianness of the bytes in the file the same as the in-memory layout?
In general I would also advise against reading structs from files. The few CPU cycles you save by doing this have mattered in the 90ies, but these day's they don't anymore. You should rather implement proper read and write code that reads and parses the fields as specified in the file format documentation, and then store them with set methods in your own in-memory representation. This makes the in-memory layout independent from the file layout, makes the code easier to debug, and easier to port if you want to switch to a different architecture or such
Your structures need to be aligned properly, look here.
Thanks for the help. I found the problem eventually by checking the size of the md3_header_t struct. There was an extra int in there (the Ofs_triangles) which shouldn't have been there. It's now reading the data perfectly so I'll get to work on the next part.
Thanks again,
Jon
My suggestion :
The code has memory leaks in constructor since you have not released memory allocated on heap .
so free the memory when its not of any use.
first you give exact values and then check
check size is properly or not