caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Felix Terkhorn <masterkh@indiana.edu>
To: dsfox@cogsci.ucsd.edu
Cc: caml-list@pauillac.inria.fr
Subject: Re: [Caml-list] Socket example
Date: Sun, 5 Aug 2001 20:57:18 -0500	[thread overview]
Message-ID: <20010805205718.A2852@indiana.edu> (raw)
In-Reply-To: <luae1ebfg0.fsf@t22.foxthompson.net>; from dsfox@cogsci.ucsd.edu on Sun, Aug 05, 2001 at 10:10:39AM -0700

[-- Attachment #1: Type: text/plain, Size: 3629 bytes --]

dsfox@cogsci.ucsd.edu wrote:
> If anyone can forward me a dead simple example of using the ocaml Unix
> module to open a socket pair to a server and reading and writing to
> it, I would be very grateful.

Here's a pretty simple example.  First of all, get two terminals open:
one is going to be your 'client' terminal, and the other, your
'server' terminal.  Run OCaml toplevel on both (one that has support
for the Unix library).  Now, on each terminal, type this:


let sock = socket PF_INET SOCK_STREAM 0;;


This will give you an unconnected/unbound socket descriptor with which
to play.  Now, on the server terminal, type:


bind sock (ADDR_INET (inet_addr_of_string "127.0.0.1",55555));;
listen sock;;
let (client_sock,client_addr) = accept sock;;



"bind" hooks up the socket to a specific IP address and port.  Here,
we use 127.0.0.1:55555.  We write inet_addr_of_string "127.0.0.1"
because OCaml expects to receive its own type of ip address
abstraction.  inet_addr_of_string creates that.  ADDR_INET simply tags
the inet_addr and port number as a 'sockaddr'.

"listen" flags the socket as "listening," ie, it should be expecting
to receive a connection from somewhere in the internet.

"accept" places the program in a wait-state until a connection has
been made with another socket.  When that connection is made, accept
returns a tuple consisting of the client socket and the address from
which the client is connecting.  The original socket is not changed:
it is now dedicated to handling "incoming calls."  Instead, a new
socket is connected on another port, and that is the socket through
which the server can communicate with its client.

Remember: the server must bind, then listen, then accept to receive
connections.


Now, on the client terminal, type:


connect sock (ADDR_INET (inet_addr_of_string "127.0.0.1",55555));;


This hooks up the socket on the client side to the socket on the
server side.

So on the client side, we can do


send sock "hello" 0 5 [];;


and that will send the string "hello" (starting at index 0, and taking
a slice of 5 characters) across the socket.  The empty list is a list
"message flags."  Since I don't know what they do, I haven't put any
in the list. :)

Then, on the server side, we can do


let buf = String.create 32;;
recv client_sock buf 0 5 [];;


recv works basically like send... and they both work more or less like
Unix.read and Unix.write.  'buf' is the string that is to be
side-effected by recv when it gets data from the socket.  If you look
at 'buf' after this call, you'll see (hopefully) 'hello' sitting at
the front of the string.

send and recv both return how many characters they sent or received,
respectively.  Keep in mind that you may have to do multiple
sends/recvs in order to get very large chunks of text across.  One way
to handle this a little more elegantly is to do something like


let (sock_in,sock_out) = 
   (in_channel_of_descr sock,out_channel_of_descr sock);;


which should work on the client side (or the server side, if you
change 'sock' to 'client_sock'), and which will let you then use all
of the pervasive library's input and output functions on the "socket
channels" you've created, eg...


output_string sock_out "i (heart) ocaml";;
flush sock_out;;
input_string sock_in  (* and hope the other side has sent something back *)


This is a lot nicer than messing with side-effecting and string
buffers, IMHO.  Just don't forget to flush. ;)

Hope this helps.

Felix


-- 
'(felix-terkhorn . masterkh@indiana.edu)

[-- Attachment #2: Type: application/pgp-signature, Size: 251 bytes --]

  reply	other threads:[~2001-08-06  1:58 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-08-04  0:05 [Caml-list] cdk & glob Alexander V. Voinov
2001-08-05 17:10 ` [Caml-list] Socket example dsfox
2001-08-06  1:57   ` Felix Terkhorn [this message]
2001-08-15 22:13   ` [Caml-list] ffi-1.2 - this version reads C header files! dsfox

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20010805205718.A2852@indiana.edu \
    --to=masterkh@indiana.edu \
    --cc=caml-list@pauillac.inria.fr \
    --cc=dsfox@cogsci.ucsd.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).