I've been scouring the internet for more information on sockets in C, but I couldn't find exactly what I was looking for.
So here's the problem:
We have to create a server that starts up two client processes that play a game.
It's a simple memory-style game that takes two numbers as inputs
if both of those two numbers correspond to the same letters,
then that spot is set to white space
else set to the letter that it corresponded to.
Where the trouble comes in is sending the same array to both clients.
Both clients can play the game fine by themselves, however, they can't play the game together.
Player 1's guesses do not appear on player 2's console.
So my question is: how can you update the array in each child process so that the same array is written to both clients?
I'm not really looking for any sample code or anything, but more of a conceptual answer/ more resources on this topic.
Thanks!
A rough pseudo code concept would be
Initialization
connectPlayers();
if(player1)
{
generateGame();
do
{
bytesSent = sendArray to other players
} while (!allBytesSent)
}
else
{
do
{
bytesRead = readArray from server
} while (!allBytesRead)
}
Game Loop
while(!gameComplete)
{
if(!firstTime through as player 1)
{
waitforyourTurn();
read and update Game State; //reads another players guess and update array
}
result = doAGuess();
sendGuess(result); //sends guess to other player
passTurnToNextPlayer();
}
Related
I have an issue of an if statement not passing whilst my system gatt connection is not made.
Context
I have a BLE system using a NRF52840-dk board programmed in C. I also have a mobile application which, communicates with this board via a Gatt connection. I have a single service with a single characteristic. I write to this characteristic from my mobile application and, from this do some processing. At the moment I can send over a timestamp and begin storing data. However, I need to then send data back to my mobile device by this connection.
So what I have is a command to be sent from the phone to ask for some data. This should then send data back to the phone by changing the characteristic value.
Before I can change the value I need to see if the command has been issued. However, due to the priorities and constraints of the device I need to do this processing in the main function not in the BLE interrupt that I have done my time stamping in. This is due to the data I will be transmitting eventually will be large.
My issue however is, I receive the command to send some data back to the phone and update a global int value (changed from 0 to 1). Then in my main loop test this value and, if it is 1 write to the terminal and change the value back. I would then use this point of the code to run a function to send the data.
But this statement does not pass.
This is my main loop code
if(GATT_CONNECTED == false)//This works!
{
//Do some functions here
}
else if (GATT_CONNECTED == true)// GATT_CONNECTED = true
{
NRF_LOG_INFO("Test1 passed");//Testing variable this does not print
if(main_test == 1)
{
NRF_LOG_INFO("Test2 passed");//This does not print either irrelevant of value
main_test = 0;//False
}
idle_state_handle();
}
I don't know if the issue is the way I have defined my variable or due to interrupt priorities or something like that. But, when my Gatt connection is made the loop of (GATT_CONNECTED == true) does not seem to process.
My variable is defined in another file where my GATT connection is handled. The GATT connected variable is handled in main. my main_test variable is defined in another c file as int main_test = 0;. In the header declared as extern int main_test;.
I know the GATT_CONNECTED variable works as I have code in it that only runs when my gatt is not connected. I have omitted it for simplicity.
Any ideas,
Thanks
Ps Hope you are all keeping well and, safe
Edit
Added code for simplicity
main.c
bool GATT_CONNECTED = false;
int main(void)
{
Init_Routine();
while(1)
{
Process_data();//This runs if the gatt is not connected if statement inside
if(GATT_CONNECTED == true)//This does not run true when the gatt is connected
{
NRF_LOG_INFO("check gatt connectedpassed");//Testing variable.
nrf_gpio_pin_set(LED_4);//Turn an LED on once led 4 does not work
}
idle_state_handle();
}
}
I have to program a little game for a course in C and it has to be done with using shared-memory, semaphores and a client/server architecture which can handle multiple clients (the exact requirement for the game is 2).
The two clients need to do their turns in turns and they are represented by the very same program (no fork() involved here - both started with ./client)
The server has to create all the resources when it starts up. So my main problem is regarding the semaphores. (The shared memory and the game-logic stuff works or isn't really difficult to implement.)
To decide if the server or a client has access to the shared-memory I need one semaphore. I need a second one to decide which of the clients has access. Am I right?
So I got a hint that it could be done with assigning IDs to the clients. So the shared-memory has three additional variables like so:
struct game
{
int id_needed, client_id, id_ready;
... // additional stuff that is needed for the game logic itself
};
As the server boots up I'm initializing one semaphore to be 0 and the other one to be 1.
When the first client appears it checks if his ID is still 0 (it's initialized as zero)
If so, it tries this:
while(my_id == 0)
{
if(semaphore_down(semaphore_1) == 0) // Check if I have access to shared mem
{
shared_memory->id_needed = 1;
if(shared_memory->id_ready == 1)
{
my_id = shared_memory->client_id;
(void) printf("DEBUGGING: My ID is %d\n", my_id);
}
}
}
shared_memory->id_needed = 0;
And in the server I do ...
while(1)
{
if(shared_memory->id_needed = 1)
{
(void) printf("DEBUGGING: ID is needed for another client!");
shared_memory->client_id++;
shared_memory->id_ready = 1;
(void) printf("DEBBUGING: Dispatched new ID: %d", shared_memory->client_id);
}
// If enough players, start the game ...
}
I'm really stuck here. The server just increments the ID (which is only logical), but I'm stuck as to resolve this problem.
I just want the clients to work alternately on the shared-memory and the server to check the values of the game etc.
I've never worked with semaphores before and all the documentation or examples I find do just work with one client and one server, but never multiple clients.
Please enlighten me!
I see one strange thing and two things that obviously are mistakes here
I see semaphore_down but no semaphore_up in the code you showed
you assign instead of comparing: if(shared_memory->id_needed = 1)
even if it was a comparison, it was not right anyway since compiler was free to optimize it out. Make this variable volatile to hint compiler that variable can change outside of the serial code flow. Or better declare it atomic.
I have just gotten started with Arduino and barely have any idea about more of the advanced stuff. It seems pretty straightforward. Now I'm one who usually likes to integrate two devices together, so i was wondering if i could control a servo with the computer's keyboard or two hardware push buttons attached to the Arduino board.
In case it helps, I'm using an Arduino Uno board. Here is the example code i am using to sweep the servo for now
// Sweep
// by BARRAGAN <http://barraganstudio.com>
// This example code is in the public domain.
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
void setup()
{
myservo.attach(11); // attaches the servo on pin 9 to the servo object
}
void loop()
{
for(pos = 0; pos < 45; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
for(pos = 45; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(10); // waits 15ms for the servo to reach the position
}
}
Now, let's say I wanted to change the servo's angle via pressing the
left/right arrow keys on my computer's keyboard. How would i go
about doing that?
Alternatively, what if i attached two push buttons to the Arduino,
and pressing one would move the servo either left or right depending
on the the button. Which ports would i plug the buttons into? Any
code samples or diagrams would greatly help!
To move a servo attached to an arduino attached to a computer you will need two components.
You will need software on your computer to accept keyboard commands and send commands to the arduino via the serial port. I would recommend a language like python or java to do that as a simple app can written quite easily.
Check this playground link for an example of using Java. And for an example in python check out this project.
There is a bug/feature built into the arduino that will give you grief as you go on here. The arduino is designed to auto reset when a serial connection is made to it via usb. This page has a detailed description of the issue and cites several ways to deal with it.
You will need to modify the sketch on the arduino to listen to the serial port and adjust the servo's position based on the commands received from your computer. Check out the python link above. It is an complete (hardware, pc software and arduino sketch) project designed to do something very similar to what you are trying to do.
I recommend you start with either component and try to get it going. As you run into problems, post your code and someone will be glad to help further.
As for the second question, adding buttons to the arduino is fairly simple. You will connect them to digital inputs. There are hundreds of examples on the web. Search for "add button to arduino" and see what you get. (lol... 1.3 million hits). Here again, try it and post specifics for more help.
For serial communication use putty
it is a cross platform Serial and ssh client
for the left and right arrow commands:
there are no ascii characters for arrow's: but there are utf-8;
putty or an other client sends utf-8 characters for the basic ascii characters are utf-8 and ascii exactly the same;
and the arduino reads only ascii characters;
the arduino reads
--> : 27, 91, 67
<-- : 27, 91, 68
so it is not that simple to read that.
you could use something like this
int pos = 0;
Serial.flush(); // flush all received data
while(Serial.avaialble()<3); // wait for the 3 ascii chars
if(Serial.read()==27){ // first char
if(Serial.read()==91){ //second char
switch (Serial.read()){
case 67: // Right arrow
myservo.write(++pos); // increment pos with 1 before write it
break;
case 68: // left arrow
myservo.write(--pos); // derement pos with 1 before write it
break;
case 65: // up arrow
myservo.write(++pos); // increment pos with 1 before write it
break;
case 66: // down arrow
myservo.write(--pos); // decrement pos with 1 before write it
break;
case default:
break;
}
}
}
but this is not a good solution
because of the arrow character is send in 3 bytes en when you flush it can flush the 27 so you read 91, 97, 27; and that is no valid so in doesn't work
you could write a algorithm to subtract the arrow command out of 5 ascii char's
or you can use 4 to move left and 6 to move right; which are ascii characters and in a numeric keypad are arrows drawn on those keys
For a simple command-line todo manager (that is to be implemented in C), this is what I have thought of the design:
The utility would support multiple users by storing the todo's in different files for each
While running the program would hold all the data in memory itself. This would avoid unnecessary IO and is also quite suitable when you do not expect the user to have more than 20 todos (I am assuming this is true). So, if the user already exists, the user todo file would be read and all the data captured to memory (in arrays of rows(structures)) and then when user logs out the file would be updated.
The aim of the project is to show how it can be done while keeping things very simple.
This pseudo pseudocode outlines the structure
// define data structure memory limits
// and other constants
bootup() {
// initialize data structures
}
readfile() {
use rot13();
}
writefile() {
use rot13();
}
login() {
ask_for_username
search for file or create one
if file present
readfile();
... and populate data structures
}
//1.
enter_new_task() {
read
record_time
is_starred
optional_due_date
}
//2.
...
fetch_commands() {
show_command_menu();
// 1. enter a new task
// 2. see the list of tasks
// 3. delete a task
// 4. edit a task
// 5. sort tasks by
}
while_not_logout() {
display_ui();
fetch_command();
while(command != logout) {
execute_command();
update_ui();
fetch_command();
}
writefile();
}
cleanup() {
// free memory
}
int main() {
bootup();
login();
while_not_logout();
cleanup();
}
How can I improve the program structure/execution flow?
I want to know where all can I improve the program structure before I start plugging in the actual code. Any suggestions/comments are welcome.
If you want to keep everything in memory, then only call writefile from cleanup, or from main after while_not_logout. Why not support multiple users by keeping their todo list in their own homedir?
We are working on a C language application which is simple RTSP/RTP client to record video from Axis a number of Cameras. We launch a pthread for each of the camera which establishes the RTP session and begin to record the packets captured using the recvfrom() call.
A single camera single pthread records fine for well over a day without issues.
But testing with more cameras available,about 25(so 25 pthreads), the recording to file goes fine for like 15 to 20 mins and then the recording just stops. The application still keeps running. Its been over a month and a half we have been trying with varied implementations but nothing seems to help. Please provide suggestions.
We are using CentOS 5 platform
Define "record" Does that mean write data to a file? How do you control access to the file?
You can't have several threads all trying to write at the exact same time. So the comment by Alon seems to be pertinent. Your write access control machanism has problems.
void *IPThread(void *ptr)
{
//Establish RTSP session
//Bind to RTP ports(video)
//Increase Socket buffer size to 625KB
record_fd=open(record_name, O_CREAT|O_RDWR|O_TRUNC, 0777);
while(1)
{
if(poll(RTP/RTCP ports)) //a timeout value of 1
{
if(RTCP event)
RTCPhandler();
if(RTP event)
{
recvfrom(); //the normal socket api recvfrom
WritePacketToFile(record_fd)
{
//Create new record_fd after 100MB
}
}
}
}
}
even if it is alright to stick to the single threaded implementation why is the multithreaded approach behaving such a way(not recording after ~15 mins)..?