* [Caml-list] Client/Server socket communication
@ 2002-09-18 2:51 IKEDA Katsumi
2002-09-18 3:07 ` Tim Freeman
0 siblings, 1 reply; 6+ messages in thread
From: IKEDA Katsumi @ 2002-09-18 2:51 UTC (permalink / raw)
To: caml-list
Hi,
I use Ocaml 3.06 on Vine Linux 2.1.5.
Vine Linux is RedHat 5.* and 6.* based distribution and ...
kernel: 2.2.18
libc: 6 -> 2.1.3
I make Client/Server socket communication program.
The followings are the lists.
---------------- server.ml ----------------
(* server.ml *)
let openSock port =
let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
begin
Unix.bind sock (Unix.ADDR_INET(Unix.inet_addr_any,port));
Unix.listen sock 20;
sock
end
;;
let waitChild s =
print_string "server: waitChild called\n";
flush stdout ;
let s = Unix.waitpid [ Unix.WNOHANG ] 0 in ()
;;
let main() =
Sys.set_signal Sys.sigchld (Sys.Signal_handle waitChild) ;
print_string "server started.\n";
flush stdout;
let port = 999999 in
let sock = openSock port in
begin
while true do
try
let (fd,a) = Unix.accept sock in
begin
print_string "server accepted \n";
flush stdout;
let pid = Unix.fork() in
match pid with
0 ->
begin
print_string "run a child process.\n";
flush stdout;
let buf = String.create 10 in
let ret = Unix.read fd buf 0 10 in
begin
print_string "ret = "; print_int ret; print_newline();
print_string buf; print_newline();
flush stdout;
Unix.sleep(3);
print_string "exit a child process.\n";
flush stdout;
exit 0
end
end
| _ -> (* parent process *)
begin
print_string "server parent side\n";
flush stdout ;
end
end
with
Unix.Unix_error(err, ctx1, ctx2) ->
if (err = Unix.EINTR) then
print_string "Function interrupted by signal\n"
else
begin
print_string "Unix.Unix_error in main\n";
end
| _ -> print_string "Unexpected Exception\n"
done;
end
;;
main();;
--------------------------------
---------------- client.ml ----------------
let main() =
let server_address = "127.0.0.1" and port = 999999 in
let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
Unix.connect sock(Unix.ADDR_INET((Unix.inet_addr_of_string server_address),
port));
let msg = "Hello!" in
let ret = Unix.write sock msg 0 (String.length msg) in
print_string "reg = "; print_int ret; print_newline();
flush stdout;
Unix.close sock;
;;
main();;
----------------
I compiled these by ocamlc.
Now, I make run_client.sh script
---------------- run_client.sh ----------------
#!/bin/sh
./client &
./client &
./client &
./client &
./client &
./client &
./client &
./client &
./client &
./client &
--------------------------------
I run "./server &".
Then I run "./run_client.sh" several times.
I found something wrong.
I run "ps" command, it displays the following:
PID TTY TIME CMD
1225 pts/3 00:00:00 sh
3156 pts/3 00:00:00 server
3197 pts/3 00:00:00 server <defunct>
3226 pts/3 00:00:00 ps
Why "server <defunct>" is occurred.
What do I have to do to correct <defunct> ?
thanks.
--
IKEDA Katsumi <ikeda@msi.co.jp>
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Client/Server socket communication
2002-09-18 2:51 [Caml-list] Client/Server socket communication IKEDA Katsumi
@ 2002-09-18 3:07 ` Tim Freeman
2002-09-18 4:04 ` IKEDA Katsumi
2002-09-18 8:23 ` Alessandro Baretta
0 siblings, 2 replies; 6+ messages in thread
From: Tim Freeman @ 2002-09-18 3:07 UTC (permalink / raw)
To: ikeda; +Cc: caml-list
>Why "server <defunct>" is occurred.
>What do I have to do to correct <defunct> ?
This is a Unix thing, not an OCAML thing. The child will be defunct
to hold the exit status so it can be reported to the parent when the
parent waits for it, or until the parent exits.
One workaround is to wait for the child process when you expect it to exit.
Another workaround is to fork twice, so the original process is the
parent of a temporary process, and the temporary process is the parent
of the process you really wanted to create. The temporary process
exits immediately and the original parent waits for it immediately.
This leaves no defunct processes.
--
Tim Freeman
tim@fungible.com
GPG public key fingerprint ECDF 46F8 3B80 BB9E 575D 7180 76DF FE00 34B1 5C78
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Client/Server socket communication
2002-09-18 3:07 ` Tim Freeman
@ 2002-09-18 4:04 ` IKEDA Katsumi
2002-09-18 19:27 ` Tim Freeman
2002-09-18 8:23 ` Alessandro Baretta
1 sibling, 1 reply; 6+ messages in thread
From: IKEDA Katsumi @ 2002-09-18 4:04 UTC (permalink / raw)
To: caml-list
Hi,
Thank you for your quick reply.
From: tim@fungible.com (Tim Freeman)
Message-ID: <20020918031351.4EC427F4F@lobus.fungible.com>
> Another workaround is to fork twice, so the original process is the
> parent of a temporary process, and the temporary process is the parent
> of the process you really wanted to create. The temporary process
> exits immediately and the original parent waits for it immediately.
> This leaves no defunct processes.
I try this solution.
But <defunct> is occurred.
Do I misunderstand your advice?
Modified server.ml is the following.
---------------- server.ml ----------------
(* server.ml *)
let openSock port =
let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
begin
Unix.bind sock (Unix.ADDR_INET(Unix.inet_addr_any,port));
Unix.listen sock 20;
sock
end
;;
let waitChild s =
print_string "server: waitChild called\n";
flush stdout ;
let s = Unix.waitpid [ Unix.WNOHANG ] 0 in ()
;;
let run_child fd =
let pid2 = Unix.fork() in
match pid2 with
0 ->
begin
print_string "run a child process.\n";
flush stdout;
let buf = String.create 10 in
let ret = Unix.read fd buf 0 10 in
begin
print_string "ret = "; print_int ret; print_newline();
print_string buf; print_newline();
flush stdout;
Unix.sleep(5);
print_string "exit a child process.\n";
flush stdout;
exit 0
end
end
| _ ->
begin
print_string "exit temporary parent.\n";
flush stdout;
exit 0
end
;;
let main() =
Sys.set_signal Sys.sigchld (Sys.Signal_handle waitChild) ;
print_string "server started.\n";
flush stdout;
let port = 999999 in
let sock = openSock port in
while true do
try
let (fd,a) = Unix.accept sock in
begin
print_string "server accepted \n";
flush stdout;
let pid = Unix.fork() in
match pid with
0 ->
run_child fd
| _ -> (* parent process *)
begin
print_string "server parent side\n";
flush stdout ;
end
end
with
Unix.Unix_error(err, ctx1, ctx2) ->
if (err = Unix.EINTR) then
print_string "Function interrupted by signal\n"
else
begin
print_string "Unix.Unix_error in main\n";
end
| _ -> print_string "Unexpected Exception\n"
done;
;;
main();;
--------------------------------
thanks.
--
IKEDA Katsumi <ikeda@msi.co.jp>
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Client/Server socket communication
2002-09-18 3:07 ` Tim Freeman
2002-09-18 4:04 ` IKEDA Katsumi
@ 2002-09-18 8:23 ` Alessandro Baretta
1 sibling, 0 replies; 6+ messages in thread
From: Alessandro Baretta @ 2002-09-18 8:23 UTC (permalink / raw)
To: Ocaml
Tim Freeman wrote:
>>Why "server <defunct>" is occurred.
>>What do I have to do to correct <defunct> ?
>
>
> This is a Unix thing, not an OCAML thing. The child will be defunct
> to hold the exit status so it can be reported to the parent when the
> parent waits for it, or until the parent exits.
>
> One workaround is to wait for the child process when you expect it to exit.
>
> Another workaround is to fork twice, so the original process is the
> parent of a temporary process, and the temporary process is the parent
> of the process you really wanted to create. The temporary process
> exits immediately and the original parent waits for it immediately.
> This leaves no defunct processes.
>
A third workaround might be to use SIGCHLD handler to
asynchronously call wait or waitpid, but there might be
issues with the non-reentrance-with-respect-to-signals of
the libc. I doubt O'Caml could be any more signal-safe than
libc.
A fourth workaround is to use O'Caml threads, which do not
require the kernel to instantiate a new process, so no new
pid is allocated.
Alex
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Client/Server socket communication
2002-09-18 4:04 ` IKEDA Katsumi
@ 2002-09-18 19:27 ` Tim Freeman
2002-09-19 1:52 ` IKEDA Katsumi
0 siblings, 1 reply; 6+ messages in thread
From: Tim Freeman @ 2002-09-18 19:27 UTC (permalink / raw)
To: ikeda; +Cc: caml-list
>I try this solution.
>But <defunct> is occurred.
>Do I misunderstand your advice?
At the place you printed "server parent side", you should have saved
the pid that came back from fork and done a wait on it. The call to
wait should be something like
Unix.waitpid [] pid
where pid is the process id that came back from forking the temporary parent.
--
Tim Freeman
tim@fungible.com
GPG public key fingerprint ECDF 46F8 3B80 BB9E 575D 7180 76DF FE00 34B1 5C78
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Caml-list] Client/Server socket communication
2002-09-18 19:27 ` Tim Freeman
@ 2002-09-19 1:52 ` IKEDA Katsumi
0 siblings, 0 replies; 6+ messages in thread
From: IKEDA Katsumi @ 2002-09-19 1:52 UTC (permalink / raw)
To: caml-list
Hi,
From: tim@fungible.com (Tim Freeman)
Message-ID: <20020918192934.92D177F65@lobus.fungible.com>
>
> >I try this solution.
> >But <defunct> is occurred.
> >Do I misunderstand your advice?
>
> At the place you printed "server parent side", you should have saved
> the pid that came back from fork and done a wait on it. The call to
> wait should be something like
>
> Unix.waitpid [] pid
>
> where pid is the process id that came back from forking the temporary parent.
Mr. John also teach me same solution.
Now, my program works well.
Thanks.
--
IKEDA Katsumi <ikeda@msi.co.jp>
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2002-09-19 1:52 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-09-18 2:51 [Caml-list] Client/Server socket communication IKEDA Katsumi
2002-09-18 3:07 ` Tim Freeman
2002-09-18 4:04 ` IKEDA Katsumi
2002-09-18 19:27 ` Tim Freeman
2002-09-19 1:52 ` IKEDA Katsumi
2002-09-18 8:23 ` Alessandro Baretta
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).