From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id DAA04047; Mon, 6 Aug 2001 03:58:28 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id DAA04371 for ; Mon, 6 Aug 2001 03:58:26 +0200 (MET DST) Received: from tingod.ffh.ac (cv-3-130.campusview.indiana.edu [149.159.3.130]) by concorde.inria.fr (8.11.1/8.10.0) with ESMTP id f761wKb29519 for ; Mon, 6 Aug 2001 03:58:25 +0200 (MET DST) Received: (from hongo@localhost) by tingod.ffh.ac (8.11.0/8.11.0) id f761vIx02971; Sun, 5 Aug 2001 20:57:18 -0500 Date: Sun, 5 Aug 2001 20:57:18 -0500 From: Felix Terkhorn To: dsfox@cogsci.ucsd.edu Cc: caml-list@pauillac.inria.fr Subject: Re: [Caml-list] Socket example Message-ID: <20010805205718.A2852@indiana.edu> References: <3B6B3C57.7BC4EC1C@quasar.ipa.nw.ru> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-md5; protocol="application/pgp-signature"; boundary="ReaqsoxgOBHFXBhH" Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: ; from dsfox@cogsci.ucsd.edu on Sun, Aug 05, 2001 at 10:10:39AM -0700 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk --ReaqsoxgOBHFXBhH Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable 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 =3D 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) =3D 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 =3D 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) =3D=20 (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 --=20 '(felix-terkhorn . masterkh@indiana.edu) --ReaqsoxgOBHFXBhH Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: http://cs.indiana.edu/~masterkh (public key access) iD8DBQE7bfl+d4opn1v6/rERAl5uAJ9O3k7T9dAsHPS20s6WsewilP8xhACfQVxo 9rtYZwXoggPffHVI79V7o6U= =8p6q -----END PGP SIGNATURE----- --ReaqsoxgOBHFXBhH-- ------------------- Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr