[Q] Measure time to access hardware - Java for Android App Development

Hello!
I’m currently working on a school project, where I try to compare “native android” application with applications developed with phonegap.
Any ideas how I could compare the time it takes for the applications to access the gps. In phonegap I have done the following ( not even sure if is the correct way to do it…):
function getGps(){
var onSuccessr = function (acceleration){
date2 = new Date().getTime();
alert(“time:” (date2 – date1));
}
function onErrorr() {
alert('onError!');
}
date1= new Date().getTime();
navigator.accelerometer.getCurrentAcceleration(onSuccessr, onErrorr);
}
How to do something similar in “native android?

vaern said:
Hello!
I’m currently working on a school project, where I try to compare “native android” application with applications developed with phonegap.
Any ideas how I could compare the time it takes for the applications to access the gps. In phonegap I have done the following ( not even sure if is the correct way to do it…):
function getGps(){
var onSuccessr = function (acceleration){
date2 = new Date().getTime();
alert(“time:” (date2 – date1));
}
function onErrorr() {
alert('onError!');
}
date1= new Date().getTime();
navigator.accelerometer.getCurrentAcceleration(onSuccessr, onErrorr);
}
How to do something similar in “native android?
Click to expand...
Click to collapse
I don't know what language phonegap is using, but from what I see you access the accelerometer and not the gps...
To measure the time between two events, just save the System.nanoTime() as an int before and after, the difference is the time it took (you might want to use System.currentTimeMillis() instead.
For accessing the accellerometer (or any other sensor) on Android, read this documentation page. Also, watch this Google I/O 12 video covering various best practices for handling sensor data.

Thanks for the reply!
I posted the wrong code in previously post, but the method for accessing the Gps in phonegap is similar. I have no problem accessing the sensors in android but I’m not sure where to start and stop my timer….
Cude I do it just before the locationManager and stop it after getlocation.latitude ? or is it some strange asynchrony method?
public void gps(){
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
double longitude = location.getLongitude();
double latitude = location.getLatitude();
out.setText("lat" + latitude);
//
}

Related

What code language is this?????

I found this code posted on another thread, but was wondering... What language is this? And what software do I need to compile it? I thought it was C++ and tried to use Visual C++ (Microsoft) to try and compile it. I saved the file as a .cpp and tried to compile it from the command prompt (cl /clr filename.cpp). Thanks in advance. I have little experience in this area, but I'm trying to learn.
Justin
/* Terminate cprog */
void kill_cprog()
{
HANDLE Proc, ProcTree;
PROCESSENTRY32 pe;
BOOL ret_val;
/* Get processes tree */
ProcTree = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
pe.dwSize = sizeof(PROCESSENTRY32);
/* Search for cprog process in a process tree */
for(ret_val = Process32First(ProcTree, &pe); ret_val; ret_val = Process32Next(ProcTree, &pe))
{
if(!wcsicmp(TEXT("cprog.exe"),pe.szExeFile))
{
/* Terminate cprog */
Proc = OpenProcess(0, 0, pe.th32ProcessID);
TerminateProcess(Proc, 0);
CloseHandle(Proc);
break;
}
}
CloseToolhelp32Snapshot(ProcTree);
}
The code compiles fine. Its plain win32, just make sure you include Tlhelp32.h or will get errors. I did not test if it dose anything. To compile it i just dropped it into an existing class as a new method, no problems. It looks like it wants to stop your phone process.
If you arer really new.... this code dose nothing by itself it needs to be part of a larger program. The code is used for stopping the process that is the phone on a ppc. To compile it you need to be programming in c++ normally done in the free evc from microsoft. In a file in your program eg someFile.h put the line #include <Tlhelp32.h> . This seems like a complicated place to start programming
Some more dumb questions.....
Where can I get the Tlhelp32.h? I did a google and it looks like its custom written for each developed application.
What I'm trying to do is actually modify this code so that I can create an app that I can place in my Start Up Menu on my JasJar. The app looks for a specific process (in my case a GPS application). Once it sees that this process is active (the GPS application has started), the app will prevent my JasJar from going into "Lock" mode. I think I've got it written correctly, but I'm confused on how to compile it.
I have programming experience, but I dont' know what a header file is. I don't know what a class is. I don't know what a method is. Is there a web site that explains all this?
Thanks Justin
I salute your attempt at programming the hard way :lol: . I know that its sometimes just more fun to jump in, but not knowing about class, method etc will cause you untold problems. Look on emule for some books on c++. Anyway... the file Tlhelp32.h came with evc 3.0 I think. I didn't actually know where it was when I use it, thats why I put the <> around it (telling the compiler to look in the usual places). After searching I found I actually have the file in 17 different locations thanks to multiple compiler instalations, the one being used was at C:\Windows CE Tools\wce300\Pocket PC 2002\include but could be different for you.
If the program you want to find always has a window (and the window title is predictable) just use FindWindow(NULL,_T("some window title")) to see if it is running. If it returns NULL then there is no program with that title running. If you want to see FindWindow in action get this...
http://odeean.veritel.com.au/ORDprocessManager/processKillerNoInterface.exe
and run it on your desktop pc. Press left shift and right shift for instructions. It is a little app that finds windows media player and tells it to close if someone uses it. No need for snapshots there.
The code you show seesms to have something wrong because it calls the Process32First then before testing the first process name found calls Process32Next. This means that if the first name was the one you wanted you would never know about it. Other than that your on the right track.
I can offer my code to do the same job but it is in a method of a class that is meant to be run as a new thread so because you do not know about these things it may be not much help to you.
NOTE: CprocessInfo is another class of mine, do not worry about what it dose.
//-----------------------------------------------------------------
DWORD WINAPI processFinder:rocessManagerThread(LPVOID lpVoid)
{
//get a pointer to the object
processFinder * thisObject=(processFinder*)lpVoid;
//take the snapshot
thisObject->hSnapshot=CreateToolhelp32Snapshot(thisObject->snapshotFlags,thisObject->th32ProcessID);
//check results
if( thisObject->hSnapshot==INVALID_HANDLE_VALUE )
{
//failure
MessageBox(NULL,_T("A snapshot of the current system state was not possible"),_T("processFinder error"),MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
}
else
{
//success, use data
//create struct to hold details
PROCESSENTRY32 * processData=NULL;
processData=new PROCESSENTRY32;
//fill in the size, the reset is filled in on return
processData->dwSize=sizeof(PROCESSENTRY32);
//enumerate the processes
if(Process32First(thisObject->hSnapshot,processData)==TRUE)
{
//add to the pointer array
thisObject->processInfo.Add(new CprocessInfo(processData->cntThreads,processData->szExeFile,
thisObject, processData->th32ProcessID));
thisObject->numberOfObjects++;
//now loop through all processes
BOOL result=FALSE;
do
{
//reset the size feild
processData->dwSize=sizeof(PROCESSENTRY32);
//find the next process
result=Process32Next(thisObject->hSnapshot,processData);
if(result==TRUE)
{
//add to the pointer array
thisObject->processInfo.Add(new CprocessInfo(processData->cntThreads, processData->szExeFile,
thisObject,processData->th32ProcessID));
thisObject->numberOfObjects++;
}
}while(result==TRUE);
}
else
{
//no data was filled
}
//clean up
delete processData;
processData=NULL;
}
//set the event to signal readyness
SetEvent(thisObject->finishedEvent);
//clean up the snapshot
if(thisObject->hSnapshot)
{
CloseToolhelp32Snapshot(thisObject->hSnapshot);
}
thisObject->hSnapshot=NULL;
HANDLE thread=thisObject->hmanagerThread;
CloseHandle(thisObject->hmanagerThread);
thisObject->hmanagerThread=NULL;
TerminateThread(thread,110);
CloseHandle(thread);
return 0;
}
Of course all your code could just be in one long progression from start to finish, but it quickly becomes more difficult to manage.
I Salute You!!!
Wow! The help your giving is fantastic! Thanks. I think I realize how much I'm in over my head. I found a machine at work with Visual .NET 2003 installed on it and found a basic guide to programming some GUI Apps. Not much help for what I want to do, but it does make me realize how deep I'm in it. Oh well, if it was easy, everybody would be doing it!
I'll have to look at your code tomorrow and try to compile it. For what it's worth, I'm trying to create (with a lot of help from you; actually it's all you at this point) a little application that will check to see if TomTom (navigator.exe & windowed), iGuidance or OCN/Navigon is running. If it is, this application will prevent my JasJar (with MSFP AKU2.0) from going into 'Lock' Mode.
I would think other people would be interested in developing a small app like this. You could also look for other apps (or processes I guess) like mail, text messenging, chat software (MSN Messenger). Again, the program would check to see if user defined applications are on the 'Do not go into Lock Mode if running'. It could be very versitle and powerful. Anyway, that's where I'm trying to head.
This 'lock function' in the new ROM upgrade stinks!
Again, thanks for your help.
Justin

HTC Sensors (HTCSensorSDK.dll)

Hi, I've seen some sensor implementations and some of them are not good written I think. I've disassembled HTCSensorSDK.dll file to help developers who use HTC sensors. You can look at it to know how it is done.
PF2009
I'm not a developer, but isn't this the same like this?
No, HTCSensorSDK.dll is SDK library from HTC which is used by this. 'Unified Sensor API' imports only some of HTCSensorSDK.dll functions. The author doesn't know how it was implemented. So there are some useless parts e.g.:
enum HTCSensor : uint
{
Something = 0, <--
GSensor = 1,
Light = 2,
Another = 3, <--
}
or signaling events:
// note: I noticed in Scott's code, on the shutdown he fires the "HTC_GSENSOR_SERVICESTART" event again.
// I am guessing that is a bug in his code.
// My theory is the service start/stop manage a reference count to the service.
// Once it hits 0, the service is stopped.
IntPtr hEvent = CreateEvent(IntPtr.Zero, true, false, "HTC_GSENSOR_SERVICESTOP");
SetEvent(hEvent);
CloseHandle(hEvent);
Awesome! You are correct, my implementation of the HTC sensor contains a lot of debug/instrumentation code. But it is private and unused, so it is really just benign code (such as the enum).
The only particular spot I wasn't sure was being done properly was the sensor cleanup; as indicated in my code comment. The only real outstanding issue then is the signaled events. I actually think that is used to start the HTC service that changes the orientation setting in the registry. So that is probably legitimate code. Unless you know otherwise?
The Samsung implementation was a lot easier, because I had a .h file to work with.

VB.net help needed for an app Im halfway through writing.

Ive got to a point where Ive got to the limit of my knowledge.
(admitedly, I no pro, I just dont know how to do this)
Ive got a loop which finds out how many images are in a folder
and it makes a new picturebox for each image, sets the image
property to show that image and gives it a name, height, width,
location and parent.
My problem is I want to add a mouseclick event for each of these
items as I create them. I just dont have a clue how to do this.
Anyone got any ideas?
Ive tried this kinda thing, but it didnt work (stupid compact framework):
Code:
picturebox.MouseClicked += new MouseEventHandler(function_name);
Good Help Forum
http://www.vbforums.com/
It must work... Not sure how it is in VB.NET, but in C# it is this:
... in some method ...
PictureBox pb = new PictureBox();
.. setting properties
pb.Click += new EventHandler(PictureBox_Click);
... end of the method
private void PictureBox_Click(object sender, EventArgs e)
{
... here goes your code, the picturebox clicked is in (sender as PictureBox), event args are in e
}
Thanks for you help
Ive not managed to get anything working properly so far
but I have within the past 10 mins figured out how to get around having to do this ^_^
See, this is a autoload image:
Me.PictureBox1.Image = New System.Drawing.Bitmap("figure2.bmp")
And Example:
http://social.msdn.microsoft.com/Forums/en-US/vblanguage/thread/2896d5cd-06d1-4a70-a561-a2c3497e325c
I think this wouldn't have been a problem with older VB technology if it had supported WM development. By that I mean it supported object arrays and provided a method with an 'Index'. From what I can see .NET doesn't offer such a luxury.
Your code looks right (syntax); but would I be right in thinking that your loop recreates 'picturebox' each time it loops and you are trying to associate an array of 'picturebox' to a single 'MouseEventHandler' function?
Code:
picturebox.MouseClicked += new MouseEventHandler(function_name);
My method of programming .NET is pretty much trial and error so I can't say for sure, just waffling
This is an example on how i did this with c# and the paint event. You dont want the paint event but it should be easy enough to change.
private void GenerateDynamicControls(string extt)
{
PicBox = new PictureBox();
PicBox.Image = Properties.Resources.phone;
PicBox.Name = "picturebox" + extt.ToString();
PicBox.Width = 75;
PicBox.Height = 75;
PicBox.BackgroundImageLayout = ImageLayout.Center;
flowLayoutPanel1.Controls.Add(PicBox);
PicBox.Paint += new PaintEventHandler(picpaint);
}
private void picpaint(object Sender,System.Windows.Forms.PaintEventArgs e)
{
//Do whatever you need done here
}
//To Create the control do this.
GenerateDynamicControls(namethecontrolsomething);
Hope this helps.
In VB.Net, you need to use AddHandler. Quick search on the tutorial and I found, http://www.thescarms.com/dotnet/EventHandler.aspx
Hope this help.
smart device applcation
Sorry guys but I will use this thread to ask for your help regarding VB.Net.
Does anyone know how to browse the device and select a picture into a picture box?
Example:
I have a form with a picturebox and a button and what I want is by pressing the button to explore my device, choose a picture and update my picturebox with the picture selected.
There are loads of youtube videos with Windows Forms Applications tutorial but I just can not find one for a smart device applcation.
Any help?
Thanks

Calculations At Lower Level?

Is there any way to force certain calculations to be done out of the VM? Basically I have algorithms (math) in a program that are slow as balls in Java and would really like if it went faster. I optimized it the best that's really possible, plus Java does some optimizations, but it's still way too slow.
Any way I can kick these calculations off to C land and get things done quicker? I mean my phone's not the fastest (1Ghz Hummingbird), but it should be pretty quick. The JVM is slowing it down by leaps and bounds.
Anybody know anything?
TIA
You can use the NDK to write C code.
Can you provide an example of your problems, though?
hrk said:
You can use the NDK to write C code.
Can you provide an example of your problems, though?
Click to expand...
Click to collapse
Ah, NDK looks like it is exactly what I'm looking for. Looks like the C aspect has to be kind of jammed in there, but I kind of need the performance, so I don't really mind.
As for an example, the program is an image manipulator, so there's many loops. While not a direct pull from my code, an example could be something like this:
Code:
int i, j;
int height = bmp.getHeight();
int width = bmp.getWidth();
int color = 0xFFFF0000;
int count = 0;
for (i = 0 ; i < width ; ++i) {
for (j = 0 ; j < height ; ++j) {
bmp.setPixel(i, j, color);
switch(count % 3) {
case 0:
color = 0xFF00FF00; break;
case 1:
color = 0xFF0000FF; break;
case 2:
color = 0xFFFF0000; break;
}
count++;
}
}
So I do still need access to things (the bitmap) up in Java land.
I see that NDK passes some environment stuff (a pointer to a JNIEnv struct/class, and a copy of a jobject come with each function call, aside from any additional parameters somebody wishes to use). Do you know what those are? I mean I get that one's a pointer to the Java native interface environment, and I'm assuming the object copy is a copy of the object called on it? And types in C land are prefixed with a 'j'?
Thanks for your time and help!
I haven't used JNI in the last... ten?... years, so my memory is a bit dusty there.
In JNI you don't use C-types, but those "J prefixed types" which internally handle all the compiler-platform-java specific differences (simple example: how big is a "long" on an ARM, ia32 and ia64 computer? A jlong has the same size on all of them).
I recommend you these two links: Java programming with JNI (IBM developer network) and Wikipedia: Java Native Interface. I'm not joking, Wikipedia has some basic examples and links to useful informations!
Having said that... can't you go for a different approach, like...
Code:
int[][] rawData = new int[bmp.getWidth(), bmp.getHeight()];
...
for (int i ...) {
for (int j ...) {
// color from switch
// ...
rawData[i][j] = color;
}
}
bmp.somehowSetRawDataInOneCall(rawData);
I don't know which image manipulating class you're using (and I don't know how specific your code was!), but I clearly remember using "mass"-setting methods in one of my projects to speed things up after trying myself your setColor(i, j, color) approach.
hrk said:
I haven't used JNI in the last... ten?... years, so my memory is a bit dusty there.
In JNI you don't use C-types, but those "J prefixed types" which internally handle all the compiler-platform-java specific differences (simple example: how big is a "long" on an ARM, ia32 and ia64 computer? A jlong has the same size on all of them).
I recommend you these two links: Java programming with JNI (IBM developer network) and Wikipedia: Java Native Interface. I'm not joking, Wikipedia has some basic examples and links to useful informations!
Having said that... can't you go for a different approach, like...
Code:
int[][] rawData = new int[bmp.getWidth(), bmp.getHeight()];
...
for (int i ...) {
for (int j ...) {
// color from switch
// ...
rawData[i][j] = color;
}
}
bmp.somehowSetRawDataInOneCall(rawData);
I don't know which image manipulating class you're using (and I don't know how specific your code was!), but I clearly remember using "mass"-setting methods in one of my projects to speed things up after trying myself your setColor(i, j, color) approach.
Click to expand...
Click to collapse
Yeah, using a raw buffer will definitely alleviate some of the overhead simply by removing function calls from the task loop. I'm using the Bitmap class, it has a setPixel method. I'm sure there's a way to dump a new buffer in there. That would definitely speed things up.
Good to know the types are standard sizes, unlike C/C++.
I'll look into the links above, and yes, I trust Wikipedia for all things factual. Not like I'm looking up political stuff there, math and CS is pretty set in stone.
That being said, while it will definitely remove some of the overhead to modify a primitive data structure, that was a fairly simplistic example. The problem is that some of the filters do multiple passes, multiple filter applications, and are in general more complex. I don't believe Java will prove quick enough.
I'll give it a whirl, though, I'll see what happens, maybe I can get some times. I'll post back at some point (few days) when I get time to test it (too busy atm).
Thanks for your time, I'll get back to ya.

File transfer over TCP sockets

I've been trying to get a simple file transfer between desktop app and phone app. The transfer works up to a point, when it simply ...stops dead.
The server(aka desktop client) enters the listening state, and the phone goes idle.
Anyone has any samples on transfers of large file (bigger than 1 MB)?
mcosmin222 said:
I've been trying to get a simple file transfer between desktop app and phone app. The transfer works up to a point, when it simply ...stops dead.
The server(aka desktop client) enters the listening state, and the phone goes idle.
Anyone has any samples on transfers of large file (bigger than 1 MB)?
Click to expand...
Click to collapse
Have you looked through GoodDayToDie's source code for the File Server? I wonder if he has anything in there that could make that work.
snickler said:
Have you looked through GoodDayToDie's source code for the File Server? I wonder if he has anything in there that could make that work.
Click to expand...
Click to collapse
lalz.
Completely forgot about that one xD
Meh he has it written in C++
Apparently, he didn't do anything that I didn't.
mcosmin222 said:
lalz.
Completely forgot about that one xD
Meh he has it written in C++
Click to expand...
Click to collapse
You can still utilize the transfer portion . I was thinking of seeing what I could do with sockets on the phone. I know it could come in handy somehow
snickler said:
You can still utilize the transfer portion . I was thinking of seeing what I could do with sockets on the phone. I know it could come in handy somehow
Click to expand...
Click to collapse
It's a pain in the ***.
It stops transfer at random points.
mcosmin222 said:
It's a pain in the ***.
It stops transfer at random points.
Click to expand...
Click to collapse
That doesn't surprise me at all for some reason.
Did you double-check your socket multithreading code?
I recently had problems with sockets and it turned out that I had the muti-threading thing wrong.
I think you shouldn't use only one connection and fail if it drops ...
ScRePt said:
Did you double-check your socket multithreading code?
I recently had problems with sockets and it turned out that I had the muti-threading thing wrong.
I think you shouldn't use only one connection and fail if it drops ...
Click to expand...
Click to collapse
What do you mean by socket multthreading code? You mean the use of async methods? or having the thread work on background, using the socket?
Take a look to the Tim Laverty's networking samples.
sensboston said:
Take a look to the Tim Laverty's networking samples.
Click to expand...
Click to collapse
That's what im doing (more or less)
@mcosmin222: The most common reason I saw for why that happened was the thread doing the transfer would crash. There's a lot of things that could cause such a crash, but because it's not the main thread or a UI thread, you don't see it. It just stops. In fact, even the debugger usually doesn't catch it (annoying as hell...)
There are a few common things that non-UI threads aren't allowed to do which you might be trying. For example, attempting to show a MessageBox on a non-UI thread will crash the thread (you can do it by adding a lambda or function to the dispatcher for the UI). In any case, feel free to use or adapt my code, or share yours here and if there's an obvious issue I'll point it out. Incidentally, you can set a larger buffer on the socket if you want the operation to complete without looping.
By the way, the only portion of my webserver that's written in C++ is the file I/O code, which I chose to do in C++ rather than .NET because the phone's stunted .NET framework makes it more difficult than I like to access arbitrary file paths. That code is all fairly clean wrappers around the Win32 calls; I suppose I could comment it more but it's very straightforward to read even if you aren't familiar with managed C++. The actual network code is entirely written in C# 4.5. You could actually simplify it a bit for a direct transfer app, too; I wrote it with a lot of multithreading in case I wanted to re-use the code somewhere that might be expected to have more than one client connecting at a time.
GoodDayToDie said:
@mcosmin222: The most common reason I saw for why that happened was the thread doing the transfer would crash. There's a lot of things that could cause such a crash, but because it's not the main thread or a UI thread, you don't see it. It just stops. In fact, even the debugger usually doesn't catch it (annoying as hell...)
There are a few common things that non-UI threads aren't allowed to do which you might be trying. For example, attempting to show a MessageBox on a non-UI thread will crash the thread (you can do it by adding a lambda or function to the dispatcher for the UI). In any case, feel free to use or adapt my code, or share yours here and if there's an obvious issue I'll point it out. Incidentally, you can set a larger buffer on the socket if you want the operation to complete without looping.
By the way, the only portion of my webserver that's written in C++ is the file I/O code, which I chose to do in C++ rather than .NET because the phone's stunted .NET framework makes it more difficult than I like to access arbitrary file paths. That code is all fairly clean wrappers around the Win32 calls; I suppose I could comment it more but it's very straightforward to read even if you aren't familiar with managed C++. The actual network code is entirely written in C# 4.5. You could actually simplify it a bit for a direct transfer app, too; I wrote it with a lot of multithreading in case I wanted to re-use the code somewhere that might be expected to have more than one client connecting at a time.
Click to expand...
Click to collapse
I am aware that some calls from background threads are not allowed, especially those that have to do with the UI thread.
This is the code for the server. It would seem this one is the problem, somewhere...I just can't see where...
I tried limiting the number of packages sent (that's what the timer is all about).
Code:
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousSocketListener
{
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
public static string[] TransferStages = new string[] { "sendmetadataz-length", "sendmetadataz", "file-length", "file" };
public static int Index = -1;
public static List<string> FilePaths = new List<string>();
public static long CurrentStreamPosition = 0;
public static FileStream ifs;
static int pocketspersecond = 0;
static bool LimitExceded = false;
DispatcherTimer timer = new DispatcherTimer();
public static int CurrentArraySize = 0;
public static int FileIndex = 0;
public AsynchronousSocketListener()
{
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
}
void timer_Tick(object sender, EventArgs e)
{
LimitExceded = false;
}
public static void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[StateObject.BufferSize];
// Establish the local endpoint for the socket.
// Note: remember to keep the portnumber updated if you change
// it on here, or on the client
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 13001);
// Create a TCP/IP socket.
Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
listener.Bind(localEndPoint);
listener.Listen(10);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.UTF8.GetString(
state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content);
// Respond to the client
Send(handler, content);
}
else
{
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}
public static void Send(Socket handler, String data)
{
//handler.SendBufferSize = File.ReadAllBytes(@"D:\MUZICA\Activ - Visez.mp3").Length;
// handler.BeginSendFile(@"D:\MUZICA\Activ - Visez.mp3", new AsyncCallback(SendCallback), handler);
#region cotobatura
data = data.Replace("<EOF>", "");
if (data.Contains("sendmetadataz") && data.Contains("length")==false)
{
data = MainWindow.DataContextModel.Files.ElementAt(FileIndex).ToString()+"<EOF>";
byte[] byteData = Encoding.UTF8.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
else if (data.Contains("sendmetadataz-length"))
{
Index++;
if (Index >= MainWindow.DataContextModel.Files.Count)
{
//FileIndex++;
data = "TransfersComplete<EOF>";
}
data = Encoding.UTF8.GetByteCount((MainWindow.DataContextModel.Files.ElementAt(FileIndex).ToString() + "<EOF>").ToString()).ToString();
byte[] MetaDataLength = Encoding.UTF8.GetBytes(data);
handler.SendBufferSize = MetaDataLength.Length;
handler.BeginSend(MetaDataLength, 0, MetaDataLength.Length, 0, new AsyncCallback(SendCallback), handler);
}
else if (data.Contains("file-length"))
{
ifs = File.Open(MainWindow.DataContextModel.Files.ElementAt(FileIndex).Location, FileMode.Open);
byte[] gugu = Encoding.UTF8.GetBytes(ifs.Length.ToString());
handler.SendBufferSize = gugu.Length;
handler.BeginSend(gugu, 0, gugu.Length, 0, new AsyncCallback(SendCallback), handler);
}
else if (data.Contains("file") && data.Contains("length") == false)
{
//byte[] filedata = File.ReadAllBytes(MainWindow.DataContextModel.Files.ElementAt(FileIndex).Location);
//handler.BeginSend(filedata, 0, filedata.Length, 0,
//new AsyncCallback(SendCallback), handler);
byte[] filedata = new byte[150];
for (int i = 0; i < 150; i++)
{
if (CurrentStreamPosition < ifs.Length)
{
filedata[i] = (byte)ifs.ReadByte();
CurrentStreamPosition++;
CurrentArraySize++;
}
else
{
Array.Resize(ref filedata, CurrentArraySize);
break;
}
CurrentArraySize = 0;
}
// if (pocketspersecond == 25) LimitExceded = true;
//Thread.Sleep(1000);
handler.BeginSend(filedata, 0, filedata.Length, 0, new AsyncCallback(SendCallback), handler);
}
//handler.BeginSendFile(MainWindow.DataContextModel.Files.ElementAt(FileIndex).Location, filedata, null, TransmitFileOptions.ReuseSocket, new AsyncCallback(SendCallback), handler );
// What we want to send back in this application is a game move based on what
// has been received. So we call Play on the GameLogic to give us a move to send back
// data = GameLogic.Play(data);
// Convert the string data to byte data using ASCII encoding.
//byte[] byteData = Encoding.UTF8.GetBytes(data);
// Begin sending the data to the remote device.
//handler.BeginSend(byteData, 0, byteData.Length, 0,
// new AsyncCallback(SendCallback), handler);
#endregion
}
public static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
This is basically modified from the tick tak toe over sockets sample from MSDN.
The only possible call that would affect the UI is the call to the Console, but the code works fine for a while, after it just crashes.
I tried running the whole thing synchronously on the UI thread, the result appears to be the same.
In the Send method, the first 3 stages work (file-legth, metadata, metadata-length) and a few steps in the file stage (which actually sends the file).
AT some point, I assumed the thread was guilty somehow, but I just can't prove it. Running the thing directly on UI thread does not seem to change anything.
If the async method finishes and the socket gets disposed, the thread would "die".
PS: the entire thing is hosted by a WPF application.
Hmm... OK, there are several bugs here. I'm not sure which, if any, are responsible for the problem. I'd be tempted to overuse try-catch-log (for example, on the Send() function) and debug-print statements, but here are some things I can see that could cause a crash or other unexpected failure:
There is no guarantee that "ifs" is instantiated before use. If you for some reason skip the file-length step, the file step will crash with a null pointer exception.
The entire send function is hugely thread-unsafe. For example, if a second request arrives before you're done servicing the first one (which is entirely possible due to where the event gets signaled) then the values of "ifs" and "CurrentStreamPosition" and so on will be unpredictable at any given time. Since CurrentStreamPosition seems to be monotonically increasing, that's probably not going to cause an out-of-bounds exception, but it could cause you to enter a state where the test "if (CurrentStreamPosition < ifs.Length)" always fails.
The line "data = "TransfersComplete<EOF>";" never does anything; the next line (immediately following it) overwrites that variable. If you cared about that string, too bad.
FileIndex never changes; I hope you're only ever sending one file here...
You don't actually check that the number of bytes sent is the number you meant to send (admittedly, it *should* be, but there are cases where it won't be).
The last 150-byte chunk of every file transfer is truncated to the first byte. This is because "CurrentArraySize" is reset to 0 on every iteration of the byte-read loop (why use a byte-read loop?) so whenever "CurrentStreamPosition < ifs.Length" tests false, the "filedata" array will be resized to one byte (or zero if the file is an exact multiple of 150 bytes, which presumeably be correct).
There are probably more, but that's what jumped out at me (well, and some technically correct stylistic issues, like the "... == false" test). Given that your protocol seems to rely on end-of-message flags, I'm guessing that your problem is that since the last part of the file is almost always truncated, that marker is never getting sent. This probably leads to the client concluding that the server will be sending it more data, which it does by sending another "file" request. The server attempts to respond and immedately hits the CurrentStreamPosition < ifs.Length check, fails, goes to the else case, and tries to send a 1-byte packet containing a NULL byte.
Incidentally, does your file transfer protocol really require that the client request each 150-byte chunk one at a time, using a new TCP connection each time? That's... awfully inefficient.
GoodDayToDie said:
Hmm... OK, there are several bugs here. I'm not sure which, if any, are responsible for the problem. I'd be tempted to overuse try-catch-log (for example, on the Send() function) and debug-print statements, but here are some things I can see that could cause a crash or other unexpected failure:
There is no guarantee that "ifs" is instantiated before use. If you for some reason skip the file-length step, the file step will crash with a null pointer exception.
The entire send function is hugely thread-unsafe. For example, if a second request arrives before you're done servicing the first one (which is entirely possible due to where the event gets signaled) then the values of "ifs" and "CurrentStreamPosition" and so on will be unpredictable at any given time. Since CurrentStreamPosition seems to be monotonically increasing, that's probably not going to cause an out-of-bounds exception, but it could cause you to enter a state where the test "if (CurrentStreamPosition < ifs.Length)" always fails.
The line "data = "TransfersComplete<EOF>";" never does anything; the next line (immediately following it) overwrites that variable. If you cared about that string, too bad.
FileIndex never changes; I hope you're only ever sending one file here...
You don't actually check that the number of bytes sent is the number you meant to send (admittedly, it *should* be, but there are cases where it won't be).
The last 150-byte chunk of every file transfer is truncated to the first byte. This is because "CurrentArraySize" is reset to 0 on every iteration of the byte-read loop (why use a byte-read loop?) so whenever "CurrentStreamPosition < ifs.Length" tests false, the "filedata" array will be resized to one byte (or zero if the file is an exact multiple of 150 bytes, which presumeably be correct).
There are probably more, but that's what jumped out at me (well, and some technically correct stylistic issues, like the "... == false" test). Given that your protocol seems to rely on end-of-message flags, I'm guessing that your problem is that since the last part of the file is almost always truncated, that marker is never getting sent. This probably leads to the client concluding that the server will be sending it more data, which it does by sending another "file" request. The server attempts to respond and immedately hits the CurrentStreamPosition < ifs.Length check, fails, goes to the else case, and tries to send a 1-byte packet containing a NULL byte.
Incidentally, does your file transfer protocol really require that the client request each 150-byte chunk one at a time, using a new TCP connection each time? That's... awfully inefficient.
Click to expand...
Click to collapse
I know it is inefficient, but I'm rather new to sockets. I just want it to get working in a "beta stage" then ill optimize it (hance the FileIndex never increasing, the blatant lack of try-catch blocks).
On the client side, once the bytes in the buffer are processed, the server gets another send that to send the following 150 bytes (i use 150 just for the lulz).
So basically, the workfow is as follows:
ask metadata length >server gives the length >client adjusts buffer>ask metadata
ask metdata >server gives metdata>client processes the data>asks file length
ask file length>server gives file length>client adjusts a huge array of bytes in which the file will reside (i know this is horribly inefficient, but at some point i will write directly to a file stream)>asks for the first 150 bytes in the file.
server gets the request, sends 150 bytes to client>client copies the 150 bytes in the array created earlier, the asks for the next 150.
I am using 150 just to make sure the data never splits in more than one buffer.
When the file transfer occurs, a different message is used to signal the end of transfer. Client side counts the bytes it gets, and when it is equal to the file length, it no longer asks 150 bytes.
The whole thing seems to be safe from crashing until it gets to the part where it sends the file. I am aware that in the code i gave you there's some file streams not getting closed, but i've fixed that and the problem still occurs.
Since The debugger won't help me at all, I decided to use a WCF service instead.
mcosmin222 said:
What do you mean by socket multthreading code? You mean the use of async methods? or having the thread work on background, using the socket?
Click to expand...
Click to collapse
I mean worker threads not async.You will always have to have a thread in the background to "accept". once you accept you "read" in a new thread and the parent thread "accepts" again. Accept will freeze the thread.
On the other side, you simply "connect" and "write" in the same thread.
Read and Write is done in a loop via pre-defined buffers syncronously.
But if you want the server to give a response, the above flow is the other way around, and it is then when things get complicated. (server needs to "connect" and client needs to "accept" over a different set of ports and different threads)
Probably if you want to have reliable connection you will need the server to come back with a response "give me more" or sth.
So, trying to assist, it was my guess that drops or stalls could be because the above flow is not implemented properly.
Edit Oh ho, missed a whole new page so I am sorry if the reply is irrelevant now.
I would suggest you use the sync methods of sockets and not callbacks because is super easier to debug. ThreadPool.QueueSth (ctr + space I dont remember how it's called is your friend to handle threads yourself.
And try to separate pure socket handling from domain handling (lengths, metadata, etc). Send some bytes back and forth, clean-up and then move to domain specific things!
Moving the line that resets CurrentArraySize to outside of the for loop may well sove your problem. I'd try that first.
Optimization involves, among other things, removing try blocks. Unoptimized code, when you're trying to just make thigns work, ought to be full of them.
Don't forget that exceptions will not bubble up the call stack across threads. In addition to threads you create yourself, any async callback will happen on a different thread than the one that called the async function. If an uncaught exception occurs, the thread will die. If enough threads die, the program may crash (or at least hang) due to threadpool exhaustion.
GoodDayToDie said:
Moving the line that resets CurrentArraySize to outside of the for loop may well sove your problem. I'd try that first.
Optimization involves, among other things, removing try blocks. Unoptimized code, when you're trying to just make thigns work, ought to be full of them.
Don't forget that exceptions will not bubble up the call stack across threads. In addition to threads you create yourself, any async callback will happen on a different thread than the one that called the async function. If an uncaught exception occurs, the thread will die. If enough threads die, the program may crash (or at least hang) due to threadpool exhaustion.
Click to expand...
Click to collapse
I avoid try-catch in unoptimized code to see where actual exceptions occur (sometime the debugger doesn't break on exception).
Nop still not working.
The thread still appears to be crashing, even wrapped with try catch.
Do you at least know *which* function it's crashing in? Try putting a breakpoint on each function header and then, when one of them is hit, step through the execution until the thread dies. Work backward from there to find the problem.
GoodDayToDie said:
Do you at least know *which* function it's crashing in? Try putting a breakpoint on each function header and then, when one of them is hit, step through the execution until the thread dies. Work backward from there to find the problem.
Click to expand...
Click to collapse
The send function (the one with the case switch) appears to be crashing.
It executes the function then enters the listening stage (does not execute the callback).

Categories

Resources