I'm trying create server application in C++ using RakNet.
When i try following code :
#include <stdio.h>
#include "RakPeerInterface.h"
#define MAX_CLIENTS 10
#define SERVER_PORT 60000
int main(void)
{
char str[512];
RakNet::RakPeerInterface *peer = RakNet::RakPeerInterface::GetInstance();
bool isServer;
printf("(C) or (S)erver?\n");
gets(str);
if ((str[0] == 'c') || (str[0] == 'C'))
{
SocketDescriptor sd;
peer->Startup(1, &sd, 1);
isServer = false;
}
else {
SocketDescriptor sd(SERVER_PORT, 0);
peer->Startup(MAX_CLIENTS, &sd, 1);
isServer = true;
}
// TODO - Add code body here
RakNet::RakPeerInterface::DestroyInstance(peer);
return 0;
}
Compiler giving this errors :
I guess i set up RakNet successfully What is missing ?
Well, one that that seems to be missing - if you are using the RakNet SocketDescriptor object is the "RakNet::" part to elt it know which namespace to use?
You have it on the PeerInterface section, but then have not used it on the SocketDescriptor
Also the RakNet socket descriptors are part of the "#include "RakNetTypes.h"" as far as I remember.. which also seems to be missing.. so unless youre using other SocketDescriptors .. that may also be needed :o
Missed the "Gets" part too - there is header for that under "#include "Gets.h"" within Raknet as well
Related
I've got a situation to develop a code that can have only one instance per machine any time. And my code should be platform independent. Till this it is fine, but the problem is that I cannot have any other files except my binary. I've developed a code using fcntl, my logic is that I'll lock my binary itself, so every time the code runs it checks if it could lock and returns if it can't. This logic worked fine in ubuntu, solaris machines, but in windows I found that this logic no longer works as I can't open the running exe file. Here I attached my code where I got stuck. Please excuse me if you feel it's not the correct portal to ask, or if you feel my research is of no use. Any suggestion will be of great help to me.
#include<iostream>
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
#define PATH "<my binary path>"
using namespace std;
int main(){
int lockfd;
FILE *FP = fopen(PATH,"wb");
if (!FP)
{
if(errno==16){
cout<<"programme is currently running hence I quit\n";// windows
}else{
cout<<"error while opening the given file\n";
cout<<"errno = "<<errno<<"\n";
}
return 1;
}else{
lockfd = fileno(FP);
}
cout<<lockfd<<"\n";
cout<<"errno = "<<errno<<"\n";
struct flock lock;
lock.l_start = 0;
lock.l_len = 0;
lock.l_type = F_WRLCK;//F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_pid = getpid();
int rc = fcntl(lockfd, F_SETLK, &lock);
cout<<"rc = "<<rc<<"\n";
cout<<"errno = "<<errno<<" eagain ="<<EAGAIN<<"\n";
if (rc == -1 && errno == EAGAIN) {
cout<<"cant lock now hence I quit\n";
return 0;
}else{
cout<<"lock done\n";
sleep(10);
//rest of the code//
}
}
The simpliest edit to make would be
#ifndef WIN32
#define PATH "/export/home/dath/Desktop/singleTon.bin"
#else
#define PATH "<some path in C that you want>"
#endif
Which forces the path to be one thing for windows, and something else for all other platforms.
That said there are other cleaner ways of doing this such as shared memory which would mean that you wouldn't have to worry about leaving files around the place or hard-coding their path.
I am trying JackAudio with c++ on Windows 8.1 and it works.
I am using a simple client code that can be found on the git. This code should send a low pitch signal to one hear and a high pitch signal to the other but for me it sends both signals to both hear.
I don't know what is wrong since two are registered and both get access to the correct speakers.
/** #file simple_client.c
*
* #brief This simple client demonstrates the basic features of JACK
* as they would be used by many applications.
*/
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <signal.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <jack/jack.h>
jack_port_t *output_port1, *output_port2;
jack_client_t *client;
#ifndef M_PI
#define M_PI (3.14159265)
#endif
#define TABLE_SIZE (200)
typedef struct
{
float sine[TABLE_SIZE];
int left_phase;
int right_phase;
}
paTestData;
static void signal_handler(int sig)
{
jack_client_close(client);
fprintf(stderr, "signal received, exiting ...\n");
exit(0);
}
/**
* The process callback for this JACK application is called in a
* special realtime thread once for each audio cycle.
*
* This client follows a simple rule: when the JACK transport is
* running, copy the input port to the output. When it stops, exit.
*/
int
process(jack_nframes_t nframes, void *arg)
{
jack_default_audio_sample_t *out1, *out2;
paTestData *data = (paTestData*)arg;
int i;
out1 = (jack_default_audio_sample_t*)jack_port_get_buffer(output_port1, nframes);
out2 = (jack_default_audio_sample_t*)jack_port_get_buffer(output_port2, nframes);
for (i = 0; i<nframes; i++)
{
out1[i] = data->sine[data->left_phase]; // left
out2[i] = data->sine[data->right_phase]; // right
data->left_phase += 1;
if (data->left_phase >= TABLE_SIZE) data->left_phase -= TABLE_SIZE;
data->right_phase += 10; // higher pitch so we can distinguish left and right.
if (data->right_phase >= TABLE_SIZE) data->right_phase -= TABLE_SIZE;
}
return 0;
}
/**
* JACK calls this shutdown_callback if the server ever shuts down or
* decides to disconnect the client.
*/
void
jack_shutdown(void *arg)
{
exit(1);
}
int
main(int argc, char *argv[])
{
const char **ports;
const char *client_name;
const char *server_name = NULL;
jack_options_t options = JackNullOption;
jack_status_t status;
paTestData data;
int i;
/*if (argc >= 2) { // client name specified?
client_name = argv[1];
if (argc >= 3) { // server name specified?
server_name = argv[2];
int my_option = JackNullOption | JackServerName;
options = (jack_options_t)my_option;
}
}
else { // use basename of argv[0]
client_name = strrchr(argv[0], '/');
if (client_name == 0) {
client_name = argv[0];
}
else {
client_name++;
}
}*/
client_name = "mytest";
for (i = 0; i<TABLE_SIZE; i++)
{
data.sine[i] = 0.2 * (float)sin(((double)i / (double)TABLE_SIZE) * M_PI * 2.);
}
data.left_phase = data.right_phase = 0;
// open a client connection to the JACK server
client = jack_client_open(client_name, options, &status, server_name);
if (client == NULL) {
fprintf(stderr, "jack_client_open() failed, "
"status = 0x%2.0x\n", status);
if (status & JackServerFailed) {
fprintf(stderr, "Unable to connect to JACK server\n");
}
exit(1);
}
if (status & JackServerStarted) {
fprintf(stderr, "JACK server started\n");
}
if (status & JackNameNotUnique) {
client_name = jack_get_client_name(client);
fprintf(stderr, "unique name `%s' assigned\n", client_name);
}
// tell the JACK server to call `process()' whenever
//there is work to be done.
jack_set_process_callback(client, process, &data);
// tell the JACK server to call `jack_shutdown()' if
//it ever shuts down, either entirely, or if it
//just decides to stop calling us.
jack_on_shutdown(client, jack_shutdown, 0);
// create two ports
output_port1 = jack_port_register(client, "output1",
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
output_port2 = jack_port_register(client, "output2",
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if ((output_port1 == NULL) || (output_port2 == NULL)) {
fprintf(stderr, "no more JACK ports available\n");
exit(1);
}
//Tell the JACK server that we are ready to roll. Our
// process() callback will start running now.
if (jack_activate(client)) {
fprintf(stderr, "cannot activate client");
exit(1);
}
// Connect the ports. You can't do this before the client is
// activated, because we can't make connections to clients
// that aren't running. Note the confusing (but necessary)
// orientation of the driver backend ports: playback ports are
// "input" to the backend, and capture ports are "output" from
// it.
ports = jack_get_ports(client, NULL, NULL,
JackPortIsPhysical | JackPortIsInput);
if (ports == NULL) {
fprintf(stderr, "no physical playback ports\n");
exit(1);
}
if (jack_connect(client, jack_port_name(output_port1), ports[0])) {
fprintf(stderr, "cannot connect output ports\n");
}
if (jack_connect(client, jack_port_name(output_port2), ports[1])) {
fprintf(stderr, "cannot connect output ports\n");
}
jack_free(ports);
// install a signal handler to properly quits jack client
#ifdef WIN32
signal(SIGINT, signal_handler);
signal(SIGABRT, signal_handler);
signal(SIGTERM, signal_handler);
#else
signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler);
signal(SIGHUP, signal_handler);
signal(SIGINT, signal_handler);
#endif
// keep running until the Ctrl+C
while (1) {
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
}
jack_client_close(client);
exit(0);
}
Did you ever figure this out? I'm quite new to coding with and configuring Jack myself but my hunch is, the problem is not in the code, rather it's a mixer issue. I suspect there's a setting somewhere that has put the jack server in a mono mode of sorts which would mean all output streams are multed (yes spell checker, multed is a word in the audio engineering world :) ) to all physical audio outputs. So... stream 1 would be connected to the left and right physical output, and stream 2 would also be connected to the physical left and right outputs.
There is nothing anywhere that would necessarily say that stream 1 goes to the left output and stream 2 goes to the right... in fact, if you're running an SDDS configuration the first stream might be the left output, and the 2nd might be the left center... you wouldn't get to the right channel until you hit the 5th stream (with the 2nd, 3rd, and 4th being left center, center, and right center respectively).
Again, this is just a guess but check to see if there's a mixer or "patch bay" style application on your platform that allows you to route streams to physical outputs. In the meantime, I'll give this code a go on my system (Debian unstable/w experimental 4.3 kernel) to see what happens.
Cheers, Joe
Pardon, me - it's an old question, but for the benefit of whoever reads it... I tested this program on my System and found it works correctly!
Question to the original poster: Would you object to having this example included in the JackD example repository (https://github.com/jackaudio/example-clients)? I feel that it's a very good example on how to use the audio streaming part of the JackD API. It would probably need some small rewrite as a generic platform C program; it would be under the same license as the other examples in the JackD example repo (GPL 2). I've sent a mail to the JackD developer's list (jack-devel#lists.jackaudio.org) asking what they think.
Anyway - shewhorn had the correct hunch - nothing wrong with your code, but when you tested your program there was something wrong with the port mappings on your system (i.e. how the ports were mapped to the physical ports on your soundcard). The way to fix it is outside your application: Use some mixer or patch bay style application to route your program's streams correctly. Not your (code's) fault, your program works fine and does what you intended.
I am trying to retreive content of websice in c++ usind SDL but it is giving me this error:
'SDL_main' : must return a value
my code is:
#include <iostream>
#include "SDL.h"
#include "SDL_net.h"
#include <cstring>
int main(int argc,char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDLNet_Init();
IPaddress ip;
SDLNet_ResolveHost(&ip,"www.linux.org",80);
const char* http="GET / HTTP/1.1\nHost: www.linux.org\n\n";
TCPsocket client=SDLNet_TCP_Open(&ip);
SDLNet_TCP_Send(client,http,strlen(http)+1);
char text[10000];
while(SDLNet_TCP_Recv(client,text,10000))
std::cout << text;
SDLNet_TCP_Close(client);
SDLNet_Quit();
SDL_Quit();
}
When I put return 0; at the end, it built project but it finished immediately after that
(I am using vs2012)
UPDATE
cout<<"Some message";
doesn't print anything, is it possible that I have configured my imports wrong? are those additional dependencies right?
SDL.lib;SDL_net.lib;SDLmain.lib
I don't know what else could be wrong ...
It's because SDL defines a macro like this:
#define main SDL_main
So the function you've written is actually called SDL_main and like any other function that is not the actual main function, if it doesn't return void, you have to give it a return statement.
because your code doesn't loop forever it just returns 0 after first pass, you need to make a loop like:
while(1){
sdl_events event;
switch(event){
//handle events, drawings and so on
...
...
...
case SDL_QUIT:
exit (0);
break;
}
}
http://sdl.beuc.net/sdl.wiki/OpenGL_Full_Example
UPDATE
you may also have some problem connecting to host so you could check if connection succeed like this:
#define MAXLEN 1024
int result;
char msg[MAXLEN];
result = SDLNet_TCP_Recv(sock,msg,MAXLEN-1);
if(result <= 0) {
// TCP Connection is broken. (because of error or closure)
SDLNet_TCP_Close(sock);
exit(1);
}
else {
msg[result] = 0;
printf("Received: \"%s\"\n",msg);
}
UPDATE 2
change this:
while(SDLNet_TCP_Recv(client,text,10000))
std::cout << text;
to this:
while(SDLNet_TCP_Recv(client,text,9999))
std::cout << text;
UPDATE 3
try this, put your receive part in this if statement
if(SDLNet_SocketReady(client) == 1)
{
while(SDLNet_TCP_Recv(client,text,9999))
std::cout << text;
}
if this still doesn't work I suggest to use QT sockets or Boost asio, both async and more intuitive
Using inotify to monitor a directory for any new file created in the directory by adding a watch on the directory by
fd = inotify_init();
wd = inotify_add_watch(fd, "filename_with_path", IN_CLOSE_WRITE);
inotify_add_watch(fd, directory_name, IN_CLOSE_WRITE);
const int event_size = sizeof(struct inotify_event);
const int buf_len = 1024 * (event_size + FILENAME_MAX);
while(true) {
char buf[buf_len];
int no_of_events, count = 0;
no_of_events = read(fd, buf, buf_len);
while(count < no_of_events) {
struct inotify_event *event = (struct inotify_event *) &buf[count];
if (event->len) {
if (event->mask & IN_CLOSE_WRITE) {
if (!(event->mask & IN_ISDIR)) {
//It's here multiple times
}
}
}
count += event_size + event->len;
}
When I scp a file to the directory, this loops infinitely. What is the problem with this code ? It shows the same event name and event mask too. So , it shows that the event for the same, infinite times.
There are no break statements. If I find an event, I just print it and carry on waiting for another event on read(), which should be a blocking call. Instead, it starts looping infinitely. This means, read doesn't block it but returns the same value for one file infinitely.
This entire operation runs on a separate boost::thread.
EDIT:
Sorry all. The error I was getting was not because of the inotify but because of sqlite which was tricky to detect at first. I think I jumped the gun here. With further investigation, I did find that the inotify works perfectly well. But the error actually came from the sqlite command : ATTACH
That command was not a ready-only command as it was supposed to. It was writing some meta data to the file. So inotify gets notification again and again. Since they were happening so fast, it screwed up the application.I finally had to breakup the code to understand why.
Thanks everyone.
I don't see anything wrong with your code...I'm running basically the same thing and it's working fine. I'm wondering if there's a problem with the test, or some part of the code that's omitted. If you don't mind, let's see if we can remove any ambiguity.
Can you try this out (I know it's almost the same thing, but just humor me) and let me know the results of the exact test?
1) Put the following code into test.c
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/inotify.h>
int main (int argc, char *argv[])
{
char target[FILENAME_MAX];
int result;
int fd;
int wd; /* watch descriptor */
const int event_size = sizeof(struct inotify_event);
const int buf_len = 1024 * (event_size + FILENAME_MAX);
strcpy (target, ".");
fd = inotify_init();
if (fd < 0) {
printf ("Error: %s\n", strerror(errno));
return 1;
}
wd = inotify_add_watch (fd, target, IN_CLOSE_WRITE);
if (wd < 0) {
printf ("Error: %s\n", strerror(errno));
return 1;
}
while (1) {
char buff[buf_len];
int no_of_events, count = 0;
no_of_events = read (fd, buff, buf_len);
while (count < no_of_events) {
struct inotify_event *event = (struct inotify_event *)&buff[count];
if (event->len){
if (event->mask & IN_CLOSE_WRITE)
if(!(event->mask & IN_ISDIR)){
printf("%s opened for writing was closed\n", target);
fflush(stdout);
}
}
count += event_size + event->len;
}
}
return 0;
}
2) Compile it with gcc:
gcc test.c
3) kick it off in one window:
./a.out
4) in a second window from the same directory try this:
echo "hi" > blah.txt
Let me know if that works correctly to show output every time the file is written to and does not loop as your code does. If so, there's something important your omiting from your code. If not, then there's some difference in the systems.
Sorry for putting this in the "answer" section, but too much for a comment.
My guess is that read is returning -1 and since you dont ever try to fix the error, you get another error on the next call to read which also returns -1.
My question is really simple. Why the code below does work on Linux, and doesn't on Mac OS X 10.6.2 Snow Leopard.
To compile save the file to aio.cc, and compile with g++ aio.cc -o aio -lrt on Linux, and g++ aio.cc -o aio on Mac OS X. I'm using Mac OS X 10.6.2 for testing on a Mac, and Linux kernel 2.6 for testing on Linux.
The failure I see on OS X is aio_write fails with -1 and sets errno to EAGAIN, which simply means "Resource temporarily unavailable". Why is that?
extern "C" {
#include <aio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <signal.h>
}
#include <cassert>
#include <string>
#include <iostream>
using namespace std;
static void
aio_completion_handler(int signo, siginfo_t *info, void *context)
{
using namespace std;
cout << "BLAH" << endl;
}
int main()
{
int err;
struct sockaddr_in sin;
memset(&sin, 0, sizeof(sin));
sin.sin_port = htons(1234);
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_family = PF_INET;
int sd = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sd == -1) {
assert(!"socket() failed");
}
const struct sockaddr *saddr = reinterpret_cast<const struct sockaddr *>(&sin);
err = ::connect(sd, saddr, sizeof(struct sockaddr));
if (err == -1) {
perror(NULL);
assert(!"connect() failed");
}
struct aiocb *aio = new aiocb();
memset(aio, 0, sizeof(struct aiocb));
char *buf = new char[3];
buf[0] = 'a';
buf[1] = 'b';
buf[2] = 'c';
aio->aio_fildes = sd;
aio->aio_buf = buf;
aio->aio_nbytes = 3;
aio->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
aio->aio_sigevent.sigev_signo = SIGIO;
aio->aio_sigevent.sigev_value.sival_ptr = &aio;
struct sigaction sig_act;
sigemptyset(&sig_act.sa_mask);
sig_act.sa_flags = SA_SIGINFO;
sig_act.sa_sigaction = aio_completion_handler;
sigaction(SIGIO, &sig_act, NULL);
errno = 0;
int ret = aio_write(aio);
if (ret == -1) {
perror(NULL);
}
assert(ret != -1);
}
UPDATE (Feb 2010): OSX does not support AIO on sockets at all. Bummer!
The presented code was tested on Mountain Lion 10.8.2. It works with a small correction.
The line
"aio->aio_fildes = sd;"
should be changed for example to:
aio->aio_fildes = open( "/dev/null", O_RDWR);
to get the expected result.
see manual. "The aio_write() function allows the calling process to perform an asynchronous write to a previously opened file."
I have code very similar to yours on 10.6.2 (but writing to a file) working without any problems - so it is possible to do what you're trying.
Just out of curiosity, what value are you using for the SIGIO constant ?
I found that an invalid value here in OS X would casue aio_write to fail - so
I always pass SIGUSR1.
Maybe check the return value of sigaction() to verify the signal details?
The points raised in your links all point to a different method for raising io completion notifications (e.g. kqueue which is a BSD specific mechanism), but doesn't really answer your question re POSIX methods for async io. and whether they work on Darwin.
The UNIX world really is a mish mash of solutions for this, and it would be really good if there was one tried and tested solutiom that worked across all platforms, alas currently there's not - POSIX being the one that aims for the most consistency.
It's a bit of a stab in the dark, but it might be useful as well to set nonblocking on your socket handle ( i.e. set socket option O_NONBLOCK ) as well as using SIGUSR1
If I get some time I'll work with your socket sample and see if I can get anything out of that too.
Best of luck.
OSX Allows you to use sockets via the (CF)RunLoop. Or getting callbacks from the runloop.
That is the most elegant way I have found to use async IO on mac.
You can use your existing socket and do a CFSocketCreateWithNative. And register callbacks on your runloop.
Here is a small snippet of code that shows how it can be setup, incomplete since I have cut down on a source file...
// This will setup a readCallback
void SocketClass::setupCFCallback() {
CFSocketContext context = { 0, this, NULL, NULL, NULL };
if (CFSocketRef macMulticastSocketRef = CFSocketCreateWithNative(NULL, socketHandle_, kCFSocketReadCallBack,readCallBack, &context)) {
if (CFRunLoopSourceRef macRunLoopSrc = CFSocketCreateRunLoopSource(NULL, macMulticastSocketRef, 0)) {
if (!CFRunLoopContainsSource(CFRunLoopGetCurrent(), macRunLoopSrc, kCFRunLoopDefaultMode)) {
CFRunLoopAddSource(CFRunLoopGetCurrent(), macRunLoopSrc, kCFRunLoopDefaultMode);
macRunLoopSrc_ = macRunLoopSrc;
}
else
CFRelease(macRunLoopSrc);
}
else
CFSocketInvalidate(macMulticastSocketRef);
CFRelease(macMulticastSocketRef);
}
}
void SocketClass::readCallBack(CFSocketRef inref, CFSocketCallBackType type,CFDataRef , const void *, void *info) {
if (SocketClass* socket_ptr = reinterpret_cast<SocketClass*>(info))
socket_ptr->receive(); // do stuff with your socket
}