C++/AS3 winsock send() wont write within else if statment - c++

So, I have a server/client application, at a particular point in the code the client needs to log in to the server, so the server requsts a username and password from the client (and then checks it and blah blah blah)
heres my code,
client side (AS3)
function hwndLogKeyboard(evt:KeyboardEvent):void
{
if (evt.keyCode == 13)
{
var allow:Boolean = false;
var prompt:String;
socket.writeMultiByte("002", "us-ascii");
socket.writeByte(0);
socket.flush();
while (socket.bytesAvailable == 0)
{
trace("waiting for bytes to read");
}
prompt = socket.readMultiByte(2, "us-ascii"); //YOU WERE MISSING ); here originally updated as I was formatting, probably just copy paste error
trace(prompt);
if (prompt == "UN")//server has prompted for username information, time to send it
{
socket.writeMultiByte(inputname.text, "us-ascii");
socket.flush();
prompt = socket.readMultiByte(2, "us-ascii");
if (prompt == "PW")//server has prompted for password information, time to send it
{
socket.writeMultiByte(inputpass.text, "us-ascii");
socket.writeByte(0);
socket.flush();
}
}
//more code in here that i have commented out until this issue is resolved
}
and the server side (where im positive the problem is occuring, writtin in C++)
if(testr >= 0)
{
string dataR = string(buffer);
//data was recived from a client - analize the data to find out what it means
//signals are in the format "xxx" where 'x' is an int between 0-9
if(dataR == "001")
{
cout << "A new client has connected" << endl;
}
else if(dataR == "002")//002 is a client attempting to log-on to the server
{
cout << "Client requesting log-on" << endl;
char recvUsername[16];
const char requestUsername[3] = "UN";
char recvPassword[16];
const char requestPassword[3] = "PW";
send(Client,requestUsername,3,0);//request username from client
recv(Client,recvUsername,16,0);//got username, now time to request password
send(Client,requestPassword,16,0);//request password from client
recv(Client,recvPassword,3,0);//got password, now time to compare them against current records
cout << recvUsername << endl << recPassword << endl;
}
else if(dataR == "003")
{
cout << "A client has used chat" << endl;
}
}
else
{
cout << "error" << endl << testr << endl << WSAGetLastError << endl;
}
At first I thought it was a time issue, that perhaps the client was reading from the buffer before the server can write to it, becuase AS3 crashes becuase the read buffer is empty!
But, here's the trick, I can move my send(Client,requestUsername,3,0) to inside the if(dataR == "001") block, and it works fine. The data IS avalible for flash to read when it goes looking for it. In fact I can put that send statement almost anywhere in my server after the client's socket is created, and it works, just not where i need it to.
That's why i added the
while (socket.bytesAvailable == 0)
{
trace("waiting for bytes to read");
}
in the client, so that it would sit a loop until there was data to read, and if that had been the problem, i would have re-wrote some things to avoid that nasty while loop from having to be there. What I don't understand is that it goes into an infinite loop, flooding me with trace statements. the sever DOESN'T write the data to the socket, but from anywhere else in the code it will. I get no errors, no compiler complaints, it doesn't go out of scope or anything like that, something is just odd here.
help is much appreciated
-Tyler
still having this problem, it works everywhere else in the code except inside the 'else if' block, im completley stumped.

Related

How can identify when the other party has answered a call with PJSIP?

I am using PJSUA2 with the new c++ high level api.
I want to play a pre-recorded .wav message after the other party has answered the call. So far, PJSIP's onCallState() supports a number of events, limited to the SIP part of the call, which means that after the session part is done (e.g. the other end is ringing), the only other event to recognize is the PJSIP_INV_STATE_DISCONNECTED one.
What I am trying to do, is identify whether the other party has actually answered the call. I thought of trying to peek at the RTP side, but have not found anything so far and the documentation is not really helpful.
Anyone has done this before?
edit:
This is the code when the call is ended.
void MyCall::onCallState(OnCallStateParam& prm) {
PJ_UNUSED_ARG(prm);
CallInfo ci = getInfo();
std::cout << "*** Call: " << ci.remoteUri << " [" << ci.stateText << "]" << std::endl;
if ( ci.state == PJSIP_INV_STATE_DISCONNECTED )
{
//myAcc->removeCall(this);
/* Delete the call */
//delete this;
myAcc->removeCall(this);
delete this;
return;
}
}
The sip part ends when the invite has been sent to the other side.
Check state on equal to PJSIP_INV_STATE_CONNECTING and PJSIP_INV_STATE_CONFIRMED as established call.
https://www.pjsip.org/pjsip/docs/html/group__PJSIP__INV.htm#ga083ffd9c75c406c41f113479cc1ebc1c
And check not in CallState, but in CheckMediaState as when answering an incoming call: https://www.pjsip.org/docs/book-latest/html/call.html#working-with-call-s-audio-media
If connection establishet you get media point. And can play you .wav file:
void MyCall::onCallMediaState(OnCallMediaStateParam &prm)
{
CallInfo ci = getInfo();
// Iterate all the call medias
for (unsigned i = 0; i < ci.media.size(); i++) {
if (ci.media[i].type==PJMEDIA_TYPE_AUDIO && getMedia(i)) {
AudioMedia *aud_med = (AudioMedia *)getMedia(i);
AudioMediaPlayer player;
try {
player.createPlayer("file.wav");
player.startTransmit(*aud_med);
} catch(Error& err) {
}
}
}
}

How to get data from a specific data piece from a JSON

I'm trying to get the first accepted_answer_id.
If i print out the parsed data this is what it looks like
{"items":[{"accepted_answer_id":23249538,"question_id":23248046},{"accepted_answer_id":5582009,"question_id":5581697},{"accepted_answer_id":43114369,"question_id":43113569},{"accepted_answer_id":12120575,"question_id":12120425},{"question_id":22162858},{"accepted_answer_id":10101621,"question_id":10101556}]}
what I want is that first accepted_answer_id's numbers. So in this case all I want is 23249538. How would I go about doing this? I'm doing this using stack exchange API. This is for an assignment for school where I have to set up on our server a tool that when people ask a question gets them if available someones answer from stack overflow. This number will piped into another URL using CURL which will then grab the answer for me and print it to terminal for the user. I also want it that if there is no accepted_answer_id it just terminates the program with a failure to find answer to user.
//actually getting the data
result = curl_easy_perform(curl);
//making sure that the curl is ok and worked right
if(result != CURLE_OK)
{
cout << curl_easy_strerror(result) << endl;
return 1;
}
//making sure that the website gave info
int httpCode(0);
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode);
curl_easy_cleanup(curl);
//if website worked it will be equal to 200
if(httpCode == 200)
{
cout << "Sucessful Response From URL" << endl;
json data = json::parse(readBuffer);
cout << data << endl;
}
}
You can use a json lib for CPP, such as rapidjson (rapidjson is faster)or jsoncpp, etc.
https://github.com/Tencent/rapidjson
https://github.com/open-source-parsers/jsoncpp

Why is read() not blocking or Why is my write() sending blanks?

This is for HW A little background on my project. I am writing a client/server program. My client is to spawn my server process and then send a filename and search term to the server through a named pipe. My server is to search the file for instances of the search term and send back that it was found. It is working fine until my last two lines. After searching the whole file, the server is to tell the client the total times the search term was found. The client will then output this information in a specially formatted line. In order to tell my client that it's time for that special "total" line, I am having my server send "last line". Client should retrieve that from the pipe, go into a conditional statement to handle the special line, and then grab from the pipe the overall total from the server.
Here is my issue: my Client is recognizing the "last line" input and going into the correct conditional statement, but when It goes to grab the overall total from the pipe it always comes back blank. If there was nothing in the pipe, shouldn't it block? If that isn't the problem, why/how are blanks getting into the pipe? I have a statement proving that the overall total is getting into the pipe
client:
...
char endMessage[] ="Server-EOF";
read(fd2, buffer, maxBufferSize);
while(strcmp(buffer,endMessage) != 0)
{
if(strcmp(buffer, "final line") ==0)
{
read(fd2, buffer, maxBufferSize);
cout <<"final line buffer is:<< buffer << endl;
cout <<"Client : PID " <<clientPID << "- Target >>"<< requestedTarget
<<"<< in File >>" <<requestedFileName<< "<< " << buffer <<endl;
}
else{
cout << "Client :PID " << clientPID <<" - Target >>" <<requestedTarget
<<"<< " << buffer << endl;
}
read(fd2, buffer, maxBufferSize);
}
server:
size_t found;
getline(rf,tempLine);
while (!rf.eof())
{
currentLineNumber++;
found= tempLine.find(requestedTarget);
while(found != string::npos)
{
totalTimesFoundInFile++;
totalTimesFoundOnLine++;
found=tempLine.find(requestedTarget, found+1);
}
if(totalTimesFoundOnLine != 0)
{
int n = sprintf(stringToSend, "Appeared on Line %d, %d times",currentLineNumber,
totalTimesFoundOnLine);
write(fd2, stringToSend, sizeof(stringToSend));
}
getline(rf,tempLine);
totalTimesFoundOnLine = 0;
}
int t = sprintf(stringToSend, "Appeared a Total of %d Times",totalTimesFoundInFile);
cout <<"Final string to send: " << stringToSend <<endl;
char finalLine[] = "final line";
write(fd2, finalLine, sizeof(finalLine));
cout <<"Just put 'finalLine' into pipe" <<endl;
write(fd2, stringToSend, sizeof(stringToSend));
cout <<"Just put final string into pipe" <<endl;
char endingMessage[]="Server-EOF";
write(fd2, endingMessage, sizeof(endingMessage));
output:
Final string to send: Appeared a Total of 4 Times
Just put 'finalLine' into pipe
Just put final string into pipe
Client :PID 12684 - Target >>apple<< Appeared on Line 1, 1 times
Client :PID 12684 - Target >>apple<< Appeared on Line 2, 1 times
Client :PID 12684 - Target >>apple<< Appeared on Line 4, 2 times
final line Buffer is:
Client : PID 12684- Target >>apple<< in File >>pipedTest.txt<<
I tried to edit out things that were irrelevant, but if there is any clarification needed, I'll be watching this thread closely for a bit.
EDIT I did some checking and it looks like my server is getting all of the way through its code and returning. Could that be the issue? Does that close/clear the pipe? If so, is there a way to get my server to wait on my client before returning?

Flush queued GPIB responses

Architecture ->GBIP from external interface is connected to target ( linux) system via gpib bus.
Inside Linux box , there is ethernet cable from GPIB to motherboard.
The PIC_GPIB card on external interface is IEEE 488.2
I am sending a query from external interface to linux box.
Few scenarios
1) If I send a query which does not expect a response back , then next query send will work.
2) If I send a query which expect response back , and when I have received the response and read it and then fire next query it works fine.
3) BUT if I send a query from external interface and got response back and I ignore to read the response , then Next query fails.
I am requesting help for scenario 3.
The coding is done on linux side and its a socket programming , which uses linux inbuilt function from unistd.h for read and write.
My investigation : I have found there is a internal memory on gbib card on external interface which stores the value of previous response until we have the read. Generally I use IEEE string utility software to write commands that goes to linux box and read reposne via read button .
Could someone please direct me how to clean input buffer or memory which stores value so that write from external command contiunues without bothering to read it.
My code on linux side has been developed in C++ and socket programming. I have used in bulit write and read function to write and read to the gpib and to json server.
Sample code is shown below
bool GpibClass::ReadWriteFromGPIB()
{
bool check = true;
int n = 0;
char buffer[BUFFER_SIZE];
fd_set read_set;
struct timeval lTimeOut;
// Reset the read mask for the select
FD_ZERO(&read_set);
FD_SET(mGpibFd, &read_set);
FD_SET(mdiffFd, &read_set);
// Set Timeout to check the status of the connection
// when no data is being received
lTimeOut.tv_sec = CONNECTION_STATUS_CHECK_TIMEOUT_SECONDS;
lTimeOut.tv_usec = 0;
cout << "Entered into this function" << endl;
// Look for sockets with available data
if (-1 == select(FD_SETSIZE, &read_set, NULL, NULL, &lTimeOut))
{
cout << "Select failed" << endl;
// We don't know the cause of select's failure.
// Close everything and start from scratch:
CloseConnection(mGpibFd);
CloseConnection(mdifferntServer); // this is different server
check = false;
}
// Check if data is available from GPIB server,
// and if any read and push it to gpib
if(true == check)
{
cout << "Check data from GPIB after select" << endl;
if (FD_ISSET(mGpibFd, &read_set))
{
n = read(mGpibFd, buffer, BUFFER_SIZE);
cout << "Read from GPIB" << n << " bytes" << endl;
if(0 < n)
{
// write it to different server and check if we get response from it
}
else
{
// Something failed on socket read - most likely
// connection dropped. Close socket and retry later
CloseConnection(mGpibFd);
check = false;
}
}
}
// Check if data is available from different server,
// and if any read and push it to gpib
if(true == check)
{
cout << "Check data from diff server after select" << endl;
if (FD_ISSET(mdiffFd, &read_set))
{
n = read(mdiffFd, buffer, BUFFER_SIZE);
cout << "Read from diff servewr " << n << " bytes" << endl;
if (0 < n)
{
// Append, just in case - makes sure data is sent.
// Extra cr/lf shouldn't cause any problem if the json
// server has already added them
strcpy(buffer + n, "\r\n");
write(mGpibFd, buffer, n + 2);
std::cout <<" the buffer sixze = " << buffer << std::endl;
}
else
{
// Something failed on socket read - most likely
// connection dropped. Close socket and retry later
CloseConnection(mdiffFd);
check = false;
}
}
}
return check;
}
You should ordinarily be reading responses after any operation which could generate them.
If you fail to do that, an easy solution would be to read responses in a loop until you have drained the queue to empty.
You can reset the instrument (probably *RST), but you would probably loose other state as well. You will have to check it's documentation to see if there is a command to reset only the response queue. Checking the documentation is always a good idea, because the number of instruments which precisely comply with the spec is dwarfed by the number which augment or omit parts in unique ways.

Decrypt Firefox password database

I want to write a simple utility that extracts passwords from a Firefox password database (the corresponding file is called signons.sqlite in the profile folder).
What I've done so far: Opened database using sqlite, retrieved encrypted username, encrypted password and address of website (all stored as std::string).
So, the only thing remaining is to decrypt the username and password strings.
I tried the following (PK11Decrypt ought to store the plaintext password in plaintext):
void Firefox_Importer::PK11Decrypt(string _cipheredBuffer, char **plaintext) {
// declarations needed
SECItem * request;
SECItem * reply;
unsigned int len = (unsigned int)_cipheredBuffer.length();
const char* cipheredBuffer = (const char*)_cipheredBuffer.c_str();
// generate request and reply SECItem; seems to work properly
reply = SECITEM_AllocItem(NULL, NULL, 0);
if (reply == NULL) cout << "Error allocating SECITEM." << endl;
request = NSSBase64_DecodeBuffer(NULL, NULL, cipheredBuffer, len);
if (request == NULL) cout << "Error decoding buffer." << endl;
// the following is not working
SECStatus tmp = PK11SDR_Decrypt(request, reply, NULL);
if(tmp != SECSuccess) cout << "Something went wrong during decrypting" << endl;
*plaintext = (char*)malloc(reply->len + 1);
strncpy(*plaintext, (const char*)reply->data, reply->len);
(*plaintext)[reply->len] = '\0';
SECITEM_FreeItem(request, true);
SECITEM_FreeItem(reply, true);
}
When PK11Decrypt is called, it prints Something went wrong during decrypting, indicating that the call to PK11SDR_Decrypt didn't work properly. It always returns SECFailure (which corresponds to -1).
Does anybody have some hints or know what I'm doing wrong?
It could be that the call to PK11_Authenticate() isn't optional, even if no master password is set (yes, NSS is pretty messed up). So you might need to do the following first:
PK11SlotInfo *slot = PK11_GetInternalKeySlot();
if (!slot) cout << "Error getting internal slot" << endl;
SECStatus tmp = PK11_Authenticate(slot, PR_TRUE, NULL);
if (tmp != SECSuccess) cout << "Authentication error" << endl;
Note that I pass NULL as context to PK11_Authenticate(), the context is only required if a password prompt should be displayed.
Edit: Never mind, I noticed that PK11SDR_Decrypt() will call both functions internally. Given that you get SECFailure as result, it is likely that PK11_GetInternalKeySlot() fails which would indicate that NSS isn't initialized properly.
Firefox is opensource software. You can find the most recent source here, it is up to you to find the part where they decrypt the passwords and copy it into your application. Good luck.