How to transfer IVectorView<InkStroke> in C++/CX - c++

scenario: I would like to exchange InkStroke between devices running on the same LAN.
Step1: collect all the strokes drawn on the screen from the client:
// Send strokes to a remote server.
strokesToReplay = inkCanvas->InkPresenter->StrokeContainer->GetStrokes();
const int sz = sizeof(strokesToReplay);
char msgToSend[sz];
memcpy(msgToSend, &strokesToReplay, sz);
send(tcpClient.sockfd, msgToSend, sz, 0);
Step2: receive data from the server part:
// tcpServer is an instance of TCPServer, which contains
// a function that calls listen -> accept
// to establish a connection with the client
bytesRecv = tcpServer.recvFromClient();
// Received data was storaged in TCPServer::buffer (char buffer[16384])
What I would like to do is cast the data in the buffer into IVectorView.
So that it is possible to iterate InkStroke from it like:
for (InkStroke^ inkStroke : buffer) {
... to do
}
But here is the question: how can I cast char * to IVectorView?
I've tried memcpy() and static_cast.
But since there is no proper memory allocated in IVectorView, memcpy() will destroy the whole program.
static_cast() won't work with IVectorView.
Now I am thinking about copying the data into the clipboard, then calling the API provided by Microsoft that gets data from the clipboard and cast it into strokes automatically.
But I Do Not Know If This Works Or Not...
Is there any advice that you guys can give me?
Thank you.

Related

WebRTC Native, AudioTrackSinkInterface added to track, but OnData is never called

I've been working on a product that uses WebRTC to exchange audio between a browser and a native client, the native side being implemented in C++. Currently I've built the latest stable release of webRtc (branch: branch-heads/65).
So far, I'm able to get the connection peers to connect, audio is received and rendered correctly on the browser. However, the native client seems to never receive any data through it's audio track sink, despite the chrome debug tools suggesting that data is being sent from the browser to the native client.
The following code is definitely called, and the channel is being added as expected.
void Conductor::OnAddStream(rtc::scoped_refptr<webrtc::MediaStreamInterface> stream)
{
webrtc::AudioTrackVector atracks = stream->GetAudioTracks();
for (auto track : atracks)
{
remote_audio.reset(new Native::AudioRenderer(this, track));
track->set_enabled(true);
}
}
// Audio renderer derived from webrtc::AudioTrackSinkInterface
// In the audio renderer constructor, AddSink is called on the track.
AudioRenderer::AudioRenderer(AudioCallback* callback, webrtc::AudioTrackInterface* track) : track_(track), callback_(callback)
{
// Can confirm this point is reached.
track_->AddSink(this);
}
AudioRenderer::~AudioRenderer()
{
track_->RemoveSink(this);
}
void AudioRenderer::OnData(const void* audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels,
size_t number_of_frames)
{
// This is never hit, despite the connection starting and streams being added.
if (callback_ != nullptr)
{
callback_->OnAudioData(audio_data, bits_per_sample, sample_rate, number_of_channels, number_of_frames);
}
}
I can also confirm that both offers include the option to receive audio:
Browser client offer:
// Create offer
var offerOptions = {
offerToReceiveAudio: 1,
offerToReceiveVideo: 0
};
pc.createOffer(offerOptions)
.then(offerCreated);
Native client answer:
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions o;
{
o.voice_activity_detection = false;
o.offer_to_receive_audio = webrtc::PeerConnectionInterface::RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
o.offer_to_receive_video = webrtc::PeerConnectionInterface::RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;
}
peer_connection_->CreateAnswer(this, o);
I'm unable to find anything recent regarding this issue, and it seems like a common use case of the framework to be able to use the received audio within the client application. Any ideas for where I might be making a mistake in listening for inbound audio, or strategies for how I might take to investigate why this is not working?
Many thanks
I've managed to find an alternative approach to getting audio data from WebRTC which allows one to work around this issue.
Implement a custom webrtc::AudioDeviceModule implementation. Look at the webrtc source code to see how one might do this.
Capture the audio transport in the RegisterAudioCallback method, which is invoked when the call is established.
Snippet:
int32_t AudioDevice::RegisterAudioCallback(webrtc::AudioTransport * transport)
{
transport_ = transport;
return 0;
}
Add a custom method to device class for extracting audio from the audio transport using the NeedMorePlayData method. (Note: this seems to work with ntp_time_ms being passed in as 0, seems to not be required).
Snippet:
int32_t AudioDevice::NeedMorePlayData(
const size_t nSamples,
const size_t nBytesPerSample,
const size_t nChannels,
const uint32_t samplesPerSec,
void* audioSamples,
size_t& nSamplesOut,
int64_t* elapsed_time_ms,
int64_t* ntp_time_ms) const
{
return transport_->NeedMorePlayData(nSamples,
nBytesPerSample,
nChannels,
samplesPerSec,
audioSamples,
nSamplesOut,
elapsed_time_ms,
ntp_time_ms);
}

Best way to send data using LibEvent

I have a multi-threaded C++ app using lib event. The receive all happens in the libevent process and then a flag is set so that the data received is processed later. On the send tho, things go wrong. I am in a "main thread" and the data to send is assembled and then the following function is invoked.
int SocketWrapper :: SendData( const U8* buffer, int length )
{
if( m_useLibeventToSend )
{
bufferevent* bev = GetBufferEvent();
struct evbuffer* outputBuffer = bufferevent_get_output( bev );
evbuffer_lock( outputBuffer );
int result = evbuffer_add( outputBuffer, buffer, length );
evbuffer_unlock( outputBuffer );
return result;
}
return send( m_socketId, (const char* )buffer, length, 0 );
}
This function crashes on occasion at the point of the evbuffer_add invocation but 99.9% of the time it works fine. This smells like a concurrency bug and it may be related to clients crashing or coming-and-going. I made sure that during the initial creation of the socket by libevent, I did the following:
struct evbuffer* outputBuffer = bufferevent_get_output( GetBufferEvent() );
evbuffer_enable_locking( outputBuffer, NULL );
Do you have any notion of some other special initialization I should be doing? Should I not invoke "SendData" from my main thread and instead send an event to the bufferevent so that the send should happen in the same process as libevent?
All design ideas are open. So far, my workaround is to not use libevent for the send, but to write directly to the socket.
This crash happens in both release and debug, VS 2008, libevent 2.0. It's deep in the library so I will be resorting to including the c files in my project to try and track down my problem, but maybe someone here knows instantly what's wrong. :-)

Sending data with libevent works just sometimes

While developing it's very common that things work or they don't. When sending data from my client to my server it does not work everytime but in most cases it does. I am guessing that probably the kernel don't send the buffer it has stored. Anyways, there have to be a method to work arround this behaviour.
My client have a GUI and it have to communitcate with a server. Because threads don't work as I want them to, I decided to use event_base_loop so that it just blocks until one package is processed. After that it can do GUI stuff so that the window won't freeze.
I am very certain that my sending fails and NOT my reading because my server does not call the my callback for reading ("readcb").
The attached function i am calling from the main function like this:
int main(int argc, char **argv)
{
// init stuff
// connnect to server
sendPacket(bev);
}
I researched a lot about this, but I don't find anything. For example bufferevent_flush(bev, EV_WRITE, BEV_FLUSH) don't works with sockets (i tried it even out).
My current function for writing (in short form, simplified for one package):
void sendPacket(bufferevent * bev)
{
// just data:
const unsigned int msg_ = 12;
char msg[msg_] = "01234567891";
// send that packet:
uint16_t packet_id = 1
bufferevent_write(bev, &packet_id, 2);
bufferevent_write(bev, msg, msg_);
//and this part SHOULD make that data really send but it does not every time:
while (evbuffer_get_length(bufferevent_get_output(bev)) > 0)
{
event_base_loop(bufferevent_get_base(bev), EVLOOP_ONCE);
};
//this last one, only to be really sure (that's why i use the second option):
event_base_loop(bufferevent_get_base(bev), EVLOOP_NONBLOCK | EVLOOP_ONCE);
}
Thanks for your time, I would be lost without your help.

C++ How can I send an object via socket?

I have a question for you.
I have this class:
`
#define DIMBLOCK 128
#ifndef _BLOCCO_
#define _BLOCCO_
class blocco
{
public:
int ID;
char* data;
blocco(int id);
};
#endif
blocco::blocco(int id)
{
ID = id;
data = new char[DIMBLOCK];
}
`
and the application has a client and a server.
In the main of my server I instantiate an object of this class in this way:
blocco a(1);
After that I open a connection between the client and the server using sockets.
The question is: how can I send this object from the server to the client or viceversa?
Could you help me please?
It's impossible to send objects across a TCP connection in the literal sense. Sockets only know how to transmit and receive a stream of bytes. So what you can do is send a series of bytes across the TCP connection, formatted in such a way that the receiving program knows how to interpret them and create an object that is identical to the one the sending program wanted to send.
That process is called serialization (and deserialization on the receiving side). Serialization isn't built in to the C++ language itself, so you'll need some code to do it. It can be done by hand, or using XML, or via Google's Protocol Buffers, or by converting the object to human-readable-text and sending the text, or any of a number of other ways.
Have a look here for more info.
you can do this using serialization. This means pulling object into pieces so you can send these elements over the socket. Then you need to reconstruct your class in the other end of connection. in Qt there is QDataStream class available providing such functionality. In combination with a QByteArray you can create a data package which you can send. Idea is simple:
Sender:
QByteArray buffer;
QDataStream out(&buffer);
out << someData << someMoreData;
Receiver:
QByteArray buffer;
QDataStream in(&buffer);
in >> someData >> someMoreData;
Now you might want to provide additional constructor:
class blocco
{
public:
blocco(QDataStream& in){
// construct from QDataStream
}
//or
blocco(int id, char* data){
//from data
}
int ID;
char* data;
blocco(int id);
};
extended example
I don't know how much flak I'll get for this, but well I tried this and though I should share it. I am a beginner at socket programming so don't get pissed off.
What I did is I created an array of characters which is of the size of the class (representing the block of memory at the server side). Then I recved the block of memory at the client side and typecast that block of memory as an object and voila!! I managed to send an object from client to server.
Sample code:
blocco *data;
char blockOfData[sizeof(*data)];
if(recv(serverSocket, blockOfData, sizeof(*data), 0) == -1) {
cerr << "Error while receiving!!" << endl;
return 1;
}
data = (blocco *)blockOfData;
Now you can do whatever you want with this data using this as a pointer to the object. Just remember do not try to delete/free this pointer as this memory is assigned to the array blockOfData which is on the stack.
Hope this helps if you wanted to implement something like this.
PS: If you think what I've done is poor way of coding please let me know why. I don't know why this is such a bad idea(if it is in fact a bad idea to do this). Thanks!!

winsock, message oriented networking, and type-casting the buffer from recv

Okay, I actually don't have code as of yet because i'm just picking out a framework for the time being, but i'm still a little baffled about how i wish to go about this :.
Server side, i wish to have a class where each instance has a socket and various information identifying each connection. each object will have it's own thread for receiving data. I understand how i'll be implementing most of that, but my confusion starts just as i get to the actual transfer of data between server and client. I'll want to have a bunch of different message structs for specific cases, (for example CONNECT_MSG , DISCONNECT_MSG, POSTTEXT_MSG, etc) and then all i have to do is have a char * point at that struct and then pass it via the send() function.
But as i think on it, it gets a little complicated at that point. Any of those different message types could be sent, and on the receiving end, you will have no idea what you should cast the incoming buffer as. What i was hoping to do is, in the thread of each connection object, have it block until it receives a packet with a message, then dump it into a single queue object managed by the server(mutexes will prevent greediness) and then the server will process each message in FIFO order independent of the connection objects.
I havn't written anything yet, but let me write a little something to illustrate my setup.
#define CONNECT 1000
struct GENERIC_MESSAGE
{
int id;
}
struct CONNECT_MESSAGE : public GENERIC_MESSAGE
{
m_username;
}
void Connection::Thread()
{
while(1)
{
char buffer[MAX_BUFFER_SIZE]; // some constant(probably 2048)
recv(m_socket, buffer, MAX_BUFFER_SIZE, 0);
MESSAGE_GENERIC * msg = reinterpret_cast<MESSAGE_GENERIC *> (buffer);
server->queueMessage(msg);
}
}
void Server::QueueMessage(MESSAGE_GENERIC * msg)
{
messageQueue.push(msg);
}
void Server::Thread()
{
while(1)
{
if(!messageQueue.empty())
ProcessMessages();
else
Sleep(1);
}
}
void Server::ProcessMessages()
{
for(int i = 0; i < messageQueue.size(); i++)
{
switch(messageQueue.front()->id)
{
case CONNECT:
{
// the part i REALLY don't like
CONNECT_MESSAGE * msg = static_cast<CONNECT_MESSAGE *>(messageQueue.front() );
// do the rest of the processing on connect
break;
}
// other cases for the other message types
}
messageQueue.pop();
}
}
Now if you've been following up until now, you realize just how STUPID and fragile this is. it casts to the base class, passes that pointer to a queue, and then just assumes that the pointer is still valid from the other thread, and even then whether or not the remaining buffer after the pointer for the rest of the derived class will always be valid afterward for casting, but i have yet to find a correct way of doing this. I am wide open for ANY suggestions, either making this work, or an entirely different messaging design.
Before you write even a line of code, design the protocol that will be used on the wired. Decide what a message will consist of at the byte level. Decide who sends first, whether messages are acknowledged, how receivers identify message boundaries, and so on. Decide how the connection will be kept active (if it will be), which side will close first, and so on. Then write the code around the specification.
Do not tightly associate how you store things in memory with how you send things on the wire. These are two very different things with two very different sets of requirements.
Of course, feel free to adjust the protocol specification as you write the code.