Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[VxWK]Why my select did not work properily in VxWorks 5.4???

143 views
Skip to first unread message

Maxfield

unread,
Jan 8, 2004, 3:37:08 AM1/8/04
to
Hi

I am your products' user. I am working a project.
I plan to comunicate through the TCP/IP non-block mode.
I implemented the method by using "select". After many
times tried and by error, I completed the code. Finish
compiled and linked. The result was not followed the
designed throught. The presucode are as follow.

while(1) {
wakeup by defined period

check the return value of select, if > 0
that meaned someone was calling.

accept it.
display the message of information of client to the screen
by using "fprintf"

record the socket by fd_set

while(1) {
send the data to client
recv the ack from client
}
}

My problem was that the first time data received by client
was the message of "fprintf".

And why the "socket device" was always small, ex 3,4...
How can I enlarge the socket device to over 100.

The Same process was examed in Win2K vs Win2K, WinXP vs FreeBSD,
WinXP vs ReHat Linux 7.3. All of these did work fine.


My system is
VME7750 Single Board
VxWorks 5.4
Tornado 2.2

joe durusau

unread,
Jan 8, 2004, 8:54:40 AM1/8/04
to

Maxfield wrote:

Maybe you could clarify the question a bit?? What do you mean
by "size of socket device"? IIRC, if a socket is non-blocking,
select should always return + because the socket is by definition ready.

Could that be your problem? Also, if you are using SOCK_STREAM,
you are not guaranteed that all of the data in a signle transmission
from
the client will be returned at one time. You can get a portion of a
msg,
or several messages, or 1.5 messages, etc.

Speaking only for myself,

Joe Durusau


Maxfield

unread,
Jan 8, 2004, 9:41:10 PM1/8/04
to
joe durusau <joe.d...@lmco.com> wrote in message news:<3FFD6120...@lmco.com>...
^^^^^^^^^^^^^^^^^^^^^
server_socket = socket(AF_INET, SOCK_STREAM,0); // TCP socket
the value is always small.
I always got large number, ex 928 in Win2K envirement. But
I always got 3 or 4 in VxWorks.

> select should always return + because the socket is by definition ready.
>
> Could that be your problem? Also, if you are using SOCK_STREAM,
> you are not guaranteed that all of the data in a signle transmission
> from
> the client will be returned at one time. You can get a portion of a
> msg,
> or several messages, or 1.5 messages, etc.
>
> Speaking only for myself,
>
> Joe Durusau

timeout.tv_sec = 0;
timeout.tv_usec = 0;
iSelect = select(server_socket+1, &readfds, &writefds, NULL, &timeout);

When select detected some one was calling, it returned non-zero and positive
value to me. I used accpet to take it, then used fd_set to record it.
I display the connection information on the screen by using fprintf statement.
Then follow the self-defined handshanking rule, server send a string to
client. The client send back a string after it received the corrected string.
All done. Go through whole loop.

THE STRANGE THING IS HERE. THE CLIENT DID RECEIVE THE MESSAGE, WRONG MESSAGE.
THE MESSAGE WAS THE INFORMATION I DISPLAYED ON SCREEN.
fprintf(stdout,"CONNECTED FROM %s on PORT %d\n", inet_ntoa(from.sin_addr),
from.sin_port);
This meaned "stdout" is "server_socket".

WHAT HAPPENED? I AM GOING CRAZY. :(

closesocket(client_socket);
FD_CLR(client_socket,&readfds);
FD_CLR(client_socket,&writefds);
fromlen = sizeof(from);
client_socket= accept(server_socket, (struct sockaddr*)&from, &fromlen);
FD_SET(client_socket, &writefds);
FD_SET(client_socket, &readfds);
fprintf(stdout,"CONNECTED FROM %s on PORT %d\n", inet_ntoa(from.sin_addr),
from.sin_port);
...

send();
recv();

...

The similar code was posted to FreeBSD. Very good.

Thank joe durusau for your replied.

Joe Durusau

unread,
Jan 9, 2004, 10:29:27 AM1/9/04
to

The number returned is the filedescriptor of
the socket. vxWorks uses in general the lowest number available.
It has no other significance.

Are you seeing the fprintf message on whatever stdout is on
your system? In most versions of tornado, that's the virtual
console, not the serial port. If you don't see it anywhere
on the local system, you probably need to flush the buffer.

I can't tell what should be sent to the client, since you don't
give the parameters to send() and recv(). Also, I might oberve
that most problems like this are caused by re-use of buffers,
that is, using a single buffer for multiple things.

Speaking only for myself,

Joe Durusau

PS anybody else who sees an obvious overlook on my part,
feel free to jump right in.

Maxfield

unread,
Jan 10, 2004, 1:27:48 AM1/10/04
to
Joe Durusau <durusau...@bellsouth.net> wrote in message news:<3FFEC8D7...@bellsouth.net>...
...

Sorry, I can not catch your point - "flush the buffer". Whoese buffer?

>
> I can't tell what should be sent to the client, since you don't
> give the parameters to send() and recv(). Also, I might oberve
> that most problems like this are caused by re-use of buffers,
> that is, using a single buffer for multiple things.

Below is for server. The code sanp.

char str[128];
if(FD_ISSET(client_socket, &readfds)) {
memset(str, 0, 52);
strcpy(str, "E100000000010000000100000001000000010000000100000001");
iret = send(client_socket, str, strlen(str), 0);
...
fprintf(stdout,"SEND TO CLIENT: %s\n", str);
n = recv(client_socket, str, strlen(str), 0);
...
fprintf(stdout,"RECV ACK FROM CLIENT: %s\n", str);
...
}

And here is for client on Win2K. Sanp here.

char cBuffer[128];

...
memset(cBuffer,0,sizeof(cBuffer));
retval = recv(conn_socket,cBuffer,sizeof(cBuffer),0 );
...
printf("RECV FROM HOST: %s\n", cBuffer);
memset(cBuffer, 0, 52);
strcpy(cBuffer, "E200000000010000000100000001000000010000000100000001");
retval = send(conn_socket,cBuffer,sizeof(cBuffer),0);
...


Thanks joe again.

John

unread,
Jan 11, 2004, 4:12:40 PM1/11/04
to
Hello,

> I am your products' user.

Actually, this forum is not maintained or officially supported by Wind
River - to contact their support organisation you need to either call
your local support number or email them (mailto:sup...@windriver.com
used to work).

> I am working a project.
> I plan to comunicate through the TCP/IP non-block mode.

Is there some reason you want to use non-blocking mode? Normally, this
is not a good idea, and you would be better to have a task managing
the incoming communications for each socket you expect to need. Are
you expecting a lot of connections?

> I implemented the method by using "select". After many
> times tried and by error, I completed the code. Finish
> compiled and linked. The result was not followed the
> designed throught. The presucode are as follow.
>
> while(1) {
> wakeup by defined period
>
> check the return value of select, if > 0
> that meaned someone was calling.

I'm not sure I understand what you mean here. Later in this thread you
posted the following:

> > timeout.tv_sec = 0;
> > timeout.tv_usec = 0;
> > iSelect = select(server_socket+1, &readfds, &writefds, NULL, &timeout);

That would mean that select() would always return immediately too
since you gave it a zero timeout. You would need to check that the
reason it returned was not that it timed out before doing anything
with this. If it did, then your code would. If not, then this code is
busy waiting (a bad idea in general).

> accept it.

OK, so the socket that you had in the read FD list was the server one
I assume. I don't know why you have anything in the write FDs (I would
normally set that to be NULL, but perhaps you are planning to use
select() to deal with writing to the sockets as well?).

> display the message of information of client to the screen
> by using "fprintf"

Any reason not to just use printf()? Have you been playing with I/O
redirection at all? If so, this could explain the odd appearance of
the debug output on the end of the socket connection.

> record the socket by fd_set

OK, but I don't see why you're doing this given that the next piece of
code simply loops forever - you will never go back to the select()
call...

> while(1) {
> send the data to client
> recv the ack from client
> }
> }
>
> My problem was that the first time data received by client
> was the message of "fprintf".
>
> And why the "socket device" was always small, ex 3,4...
> How can I enlarge the socket device to over 100.

As Joe said, you do not need to. The Windoze ones are actually in
technical violation of the POSIX spec here (though for most things it
will work fine).

Now, if you mean that you want to increase the number of possible file
descriptors that can be in use simultaneously, then you need to look
at NUM_FILES, and also at increasing some of network stack buffers as
well (assuming that you are expecting all these additional FDs to be
sockets). You can find more about this in tech note 51 (or application
note 51 - can't remember the current Wind River terminology for them -
they keep changing the names of these things).

You can also find some information about these config parameters in my
Cookbook at:

http://www.bluedonkey.org/cgi-bin/twiki/bin/view/Books/VxWorksCookbookNetworking

> The Same process was examed in Win2K vs Win2K, WinXP vs FreeBSD,
> WinXP vs ReHat Linux 7.3. All of these did work fine.

Well, select() does work a little differently under VxWorks, though
normally code that was working on a BSD or Linux system should be OK.

Some things I would seriously consider though for a VxWorks
implementation are:

1) Do you really need non-blocking sockets, or could you use blocking
ones several tasks?

2) Do you really need select()? Having a task per connection, as long
as you are not expecting lots of connections, is more likely to work
reliably (remember Joe's comments about receiving partial messages
from a socket, or getting more than one message - all of these will
happen, and you will be left with some very complex code to deal with
it all.

If you have a known maximum number of connections, then you can easily
set up one task to handle the connections (i.e. block on the server
socket, and call accept() to set up the connection), and then on
worker task per active connection allowed. Each worker blocks in a
receive on the same message queue. When the main task accepts a
connection it simply sends that fd number to the message queue, and
the OS will schedule the next available worker task to handle that
connection:


(Server Socket) ---> [Server Task] ---> (Worker Queue) ---> [Worker
Task 1]
+-> [Worker
Task 2]
.
.
+-> [Worker
Task N]

This way you have no busy waiting, and no select() calls to deal with.
In fact, if you are familiar with web servers, this is how many of
them handle multiple inbound connections without saturating the
machine's resources. You can set 'N' to be suitable for your
application's maximum expected need.

The 'Worker Queue' should be at least 'N' entries deep as well, though
you can make this higher if you wish to queue more requests than you
have worker threads for (a good idea in some applications).

Each worker could be made to handle a single message and close the
connection, or it could be made to simply block on the socket until
the remote side closes the connection (you will probably need to make
sure that you have the appropriate socket options in place to detect
this - TCP_KEEPALIVE at the very least). Which you choose will depend
on your application's needs, though bear in mind that the first one
has a hidden load on the resources due to the 2*MSL timeout that TCP
imposes on tuple reuse (you can read a little about this on the
Cookbook page above as well).

The second will potentially require more worker threads (but these are
a relatively cheap resource in VxWorks, once they are spawned - I
would avoid trying to spawn them dynamically, though you could, if
need be, have a mechanism that spawned more under heavy load
conditions (say when the msgQSend() failed because the queue was
full).

HTH,
John...

=====
Contribute to the VxWorks Cookbook at: http://books.bluedonkey.org/

Maxfield

unread,
Jan 12, 2004, 8:44:50 AM1/12/04
to
john_...@yahoo.com (John) wrote in message news:<488e459a.0401...@posting.google.com>...

Here is the layout of my whole system. I used two VME7750 single boards
and one/more PC(s) to build up my system. One was running on VxWorks in
64Hz, might increase to 256Hz, I will call this as VXWORKS. The other was
running on Win2K, I will call this one as WIN2K. PC was running on WIN2K.
I will call this as PLOTTER. PLOTTER was flexible.

WIN2K give the command to command VXWORKS to work. VXWORKS send all results
to PLOTTER. There were connected by TCP/IP between/among VXWORKS and
PLOTTER(s). Thw VXWORKS was server. The PLOTTER(s) could connect to server
anytime. This controlled by WIN2K.

I had implemented the blocking mode, only for one client. It did not
worked well until I changed printf to fprintf. All messages I displayed
on screen was on right way. This was block until PLOTTER was connected.
Then my VXWORKS would go on.

OK. Why did I choose the non-blocking/select mode to implement my job?
Well, for a new guy I am, This is the only method I thought to solve my
problem.

This give me a whole new direction to implement my job. I will try it.
Only one thing how can I execute two task in my boot image after system
load the boot image?

>
> The second will potentially require more worker threads (but these are
> a relatively cheap resource in VxWorks, once they are spawned - I
> would avoid trying to spawn them dynamically, though you could, if
> need be, have a mechanism that spawned more under heavy load
> conditions (say when the msgQSend() failed because the queue was
> full).

This will not be accept from me. I could not control every status of
each spawn job.

>
> HTH,
> John...
>
> =====
> Contribute to the VxWorks Cookbook at: http://books.bluedonkey.org/

I can send you my code to you, if you wanted to see them.

Thanks, John and Joe

Joe Durusau

unread,
Jan 12, 2004, 8:33:01 PM1/12/04
to

You can spawn any number of tasks you wish in your startup code.
Of course, since there is only one CPU, you will have to ensure that
tasks that are not doing anything block on some system call, or use
taskDelay or some such to allow those with real work to run.

>
>
>>The second will potentially require more worker threads (but these are
>>a relatively cheap resource in VxWorks, once they are spawned - I
>>would avoid trying to spawn them dynamically, though you could, if
>>need be, have a mechanism that spawned more under heavy load
>>conditions (say when the msgQSend() failed because the queue was
>>full).
>
>
> This will not be accept from me. I could not control every status of
> each spawn job.
>
>
>>HTH,
>>John...
>>
>>=====
>>Contribute to the VxWorks Cookbook at: http://books.bluedonkey.org/
>
>
> I can send you my code to you, if you wanted to see them.
>
> Thanks, John and Joe

I think that overall, John's suggestions are the best idea.
If, alternatively, you wish to continue as is, you need to
at least find out the value of all the fd's you are using,
to see why msgs are going to the wrong place(s). One often
overlooked possibility is that somewhere in your code you may
be overflowing an array or you may be under or over-flowing
the stack. Checking the stack from windView would find the latter.
Finding a mishandled index is extremely difficult, but there are
some tools that help. Personally, I've never resorted to one of
them, so I cannot recommend one.

Maxfield

unread,
Jan 15, 2004, 7:46:39 PM1/15/04
to
Joe Durusau <durusau...@bellsouth.net> wrote in message news:<40034ACD...@bellsouth.net>...

Thanks Joe and John for your suggestions.
Specilly, I did not think about the stacks problem.
I will try them.
How kind of you!

0 new messages