Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Setting Thread Priority

Status
Not open for further replies.

sweep123

Technical User
May 1, 2003
185
GB
I have several threads using Send/Recv on TCP sockets- non-blocking on the Client side.

However if I do any activity on my PC I get a Bad Address when trying to send data (to the Server).

Would setting the Thread Priority higher help and how would you do this?

Or are they any settings for the socket to allow for data being a bit late?

Regards,

Sweep.
 
You say you get a 'Bad Address' problem. I recommend that you debug your code and observed the value of the pointer being passed to the send function. If that pointer is 0x00000000 or 0xcccccccc or some other errant value, then the problem is in your memory management, not in the socket.

I'm not exactly sure what's going on, but usually if you put your send/recv mechanism in a separate thread, you make them blocking sockets.

>> However if I do any activity on my PC

What is activity...

>> Would setting the Thread Priority higher help and how would you do this?

I don't think thread priority has anything to do with this problem

I REALLY hope that helps.
Will
 
apatterno,

>> However if I do any activity on my PC

What is activity...

If I run another program (just take up a bit more processing time), then one of the sockets errors out.
... and yes the pointer being passed to the send function has a value like 0xcccccccc.

But sometimes the program will run for 1/2 hour with no problems and sometimes for 5 seconds before erroring out. Also it is not always the same socket.

Currently I poll every 80msec for data on each socket. The sequence is as follows:-

Every 160msec the Server sends a command message to say provide valid data. Every 320msec the Server request the data, and I only provide valid data if I have received the command to provide valid data otherwise I provide stale data. Note I always send data back (stale or valid).

Question: Is the pointer used in the send being corrupted by timing problems or I have I an error in my code (but dont understand the error in my code as when I debug the pointer is fine).
 
>> Is the pointer used in the send being corrupted by timing problems
Bingo.

I'm really not sure about your method to "sends a command message to say provide valid data" and then "request the data, and I only provide valid data if I have received the command to provide valid data otherwise I provide stale data".

It really seems like the server is requesting data from itself, but again I get confused where this data is coming from and where it is going, and why you would want to provide stale data under certain

And making this all timing-dependent still doesn't seem like a great idea.

The 'normal' way to set up a server is with blocking calls, so that the server waits to receive data, rather than polling for it.

If a client connected through a socket requests data from the server, and the server in turn must request data from another source, here's how it should go (this is messy):
[tt]
+--------------------+ +--------------------+
| Srvr waits for req | | datasrc waits |
+--------------------+ +--------------------+
| |
blocked blocked
+------------------------+
* | Client sends a request | *
+------------------------+
unblocked < < < < < < < < < < < | *
| +------------------------+
+---------------------+ | Client waits for reply | *
| srvr processes req | +------------------------+
+---------------------+ | *
| blocked
+---------------------+ *
| srvr requests data | *
| from datasrc | *
+---------------------+ *
| > > > > > > > > > > > > > > > > > > > > > > > > unblocked
+---------------------+ * |
| srvr waits for reply| +--------------------+
+---------------------+ * | datasrc processes |
| | srvr's request |
blocked * +--------------------+
|
* * +--------------------+
| datasrc sends |
* * | reply to srvr |
+--------------------+
unblocked < < < < < < < < < < < < < < < < < < < < < < < < |
|
+---------------------+ *
| srvr sends reply |
| to client | *
+---------------------+
| > > > > > > > > > > > unblocked
|
+------------------------+
| Client receives reply. |
+------------------------+[/tt]

That seems to be what you need. Again, I get confused trying to understand your elaborate data request scheme and how sometimes you will provide stale data. And doing this on timers will only make matters worse.

P.S. I hate block diagrams [lol]

I REALLY hope that helps.
Will
 
The server wants to use non-blocking sockets (so he has control over timing issues).

The scheme is quite simple. The server can issue two commands:-

1. Turn on the data stream (from the client - otherwise stale data sent). Message sent every 160 msec - from server to client.

2. Request data from client (ever 320 msec) - data request - server requests data from client.

The client respondes to the request for data with the data (can be stale data if the data command was to switch the data stream off).

Everthing works fine until the client PC is loaded with some ther activity; e.g. run another application - then one of the sockets fails - bad address 10014 error occurs.
 
Ok, Earlier I asked if your pointer passed in to send had a value like 0xcccccccc and you said Yes. Well that usually means the pointer variable has not been initialized. That is NOT a socket problem, nor is it a timing problem. It seems like you are doing something out of order, sending data before the data exists.

Consider the simple example:

[tt]void *p;

int main(int argc, char* argv[])
{
srand(timeGetTime());

SOCKET s;
// initialize socket, etc.

SendTheData(SOCKET s);
GenerateTheData();
}

void GenerateTheData()
{
p = malloc(256);
for (int c=0; c<256; c++) {
((char*)p)[c] = (char)rand();
}
}

void SendTheData(SOCKET s)
{
send(s,p,256,0);
}[/tt]

Obviously this example is much simpler than your case, but the basic idea is this: it is up to you to ensure things happen in the right order. That's all there is to it.

You've mentioned that the program only seems to fail when there is &quot;other activity,&quot; which could mean that your program is not thread-safe. You might want to double-check that. It could also mean that the timer mechanism you're using (you still haven't told me what timer mechanism you're using) is not designed to ensure that things happen in a certain order. The Windows SetTimer/WM_TIMER mechanism certainly is not.

For example:
[tt]
#define DATA_STREAM_EVENT 2
#define REQUEST_DATA_EVENT 3

SetTimer(hwnd,DATA_STREAM_EVENT,160,NULL);
SetTimer(hwnd,REQUEST_DATA_EVENT,320,NULL);[/tt]

In the previous example, the WM_TIMER's might get sent in this order:
[tt]
+160 DATA_STREAM_EVENT

+320 DATA_STREAM_EVENT
REQUEST_DATA_EVENT
[/tt]
BUT the WM_TIMER's could also get sent in this order:
[tt]
+160 DATA_STREAM_EVENT

+320 DATA_STREAM_EVENT
REQUEST_DATA_EVENT
[/tt]
My point is, for ensuring that one certain thing happens before another, do not rely on WM_TIMER's to send in the order they were set. They are unpredictable.

If at all possible, I would steer away from any type of timers at all, for something like this. If you could, please describe in more detail the &quot;timing issues&quot; you mentioned in your previous reply.

If anyone else is following this thread, do you think you could help me out here? I really don't know what to say.

I REALLY hope that helps.
Will
 
I'm sorry, I had a mistake in my last post. This part should read:

In the previous example, the WM_TIMER's might get sent in this order:
[tt]
+160 DATA_STREAM_EVENT

+320 DATA_STREAM_EVENT
REQUEST_DATA_EVENT
[/tt]
BUT the WM_TIMER's could also get sent in this order:
[tt]
+160 DATA_STREAM_EVENT

+320 REQUEST_DATA_EVENT
DATA_STREAM_EVENT

[/tt]


I REALLY hope that helps.
Will
 
Ok, for the timers I am using Sleep(80); for an 80 msec wait period. The general logic for each socket thread is as follows:-

while(errorFree)
{
Top:
b = recv(message);
if b > 0
{
if( messageType == command)
{ set on the good data}
goto Top; // could be a data request message
if( messageType == dataRequest
{send the good data}
else
{
if(b == -1)
errorFreet = false;
}
Sleep(80);
} // end of while loop

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top