I'm having some issues with the following scenario, and I can't figure out why.
I created a tcp server in Emacs and am trying to connect to it in Gambit using open-tcp-client. Here's how I create my server in Emacs:
(make-network-process :name "grime3d" :buffer "*grime3d*" :host "localhost" :server t :service 12000 :filter 'grime3d-client-filter :log 'grime3d-server-log))
More information about `make-network-process` can be found here: http://www.gnu.org/software/emacs/manual/html_node/elisp/Network-Processes.h...
If I use telnet, everything works fine (which is why this is so odd to me):
james:~% telnet localhost 12000 Trying ::1... Connected to localhost. Escape character is '^]'. one two
However, if I use Gambit it refuses to connect:
(define p (open-tcp-client "localhost:12000")) (read p)
*** ERROR IN ##read-datum-or-label-or-none-or-dot -- Connection refused (peek-char '#<input-output-port #2 (tcp-client "localhost" 12000)>) 1>
(define p (open-tcp-client (list port-number: 12000))) (read p)
*** ERROR IN ##read-datum-or-label-or-none-or-dot -- Connection refused (peek-char '#<input-output-port #3 (tcp-client #u8(127 0 0 1) 12000)>) 1>
If I create a server in Gambit, like this, it works as expected:
---------------- process 1
(define p (open-tcp-server "*:30000")) (read p)
#<input-output-port #2 (tcp-client)>
(read p)
#<input-output-port #3 (tcp-client)>
---------------- process 2
(define p (open-tcp-client "localhost:30000")) (define p (open-tcp-client "localhost:30000"))
So, it all points to some weird interaction between Gambit and the Emacs server. I've looked around and even scanned through the Emac source for `make-network-process` and it all seems normal. I'm not really experienced with client-server systems though. Am I doing something obviously wrong?
- James
Afficher les réponses par date
Forgot the important stuff:
james:~% gsc -v v4.5.1 20090807004037 i386-apple-darwin10.0.0 "./configure --prefix=/usr/local" james:~% uname -a Darwin james.local 10.0.0 Darwin Kernel Version 10.0.0: Fri Jul 31 22:47:34 PDT 2009; root:xnu-1456.1.25~1/RELEASE_I386 i386
On Fri, Oct 2, 2009 at 1:57 AM, James Long longster@gmail.com wrote:
... So, it all points to some weird interaction between Gambit and the Emacs server. I've looked around and even scanned through the Emac source for `make-network-process` and it all seems normal. I'm not really experienced with client-server systems though. Am I doing something obviously wrong?
- James
Hi James.
I run Gambit-C v4.5.1
Knowing nothing about grime, I added in a .emacs
(defun dummy-f (&rest x) (print x)) (make-network-process :name "grime3d" :buffer "*grime3d*" :host "localhost" :server t :service 12000 :filter 'dummy-f :log 'dummy-f))
And fired gsi
(define p (open-tcp-client "localhost:12000")) (read p)
"Nothing happens", it blocks
(define p (open-tcp-client "localhost:12000")) (with-output-to-port p (lambda () (pretty-print "lol" p))) (force-output p)
It expectedly prints lol in emacs
I can't help you more with that.
P!
On 2-Oct-09, at 1:57 AM, James Long wrote:
I'm having some issues with the following scenario, and I can't figure out why.
I created a tcp server in Emacs and am trying to connect to it in Gambit using open-tcp-client. Here's how I create my server in Emacs:
(make-network-process :name "grime3d" :buffer "*grime3d*" :host "localhost" :server t :service 12000 :filter 'grime3d-client-filter :log 'grime3d-server-log))
More information about `make-network-process` can be found here: http://www.gnu.org/software/emacs/manual/html_node/elisp/Network-Processes.h...
In my own experiments to get Gambit and emacs talking over TCP I have used this incantation:
(make-network-process :name process-name :buffer buffer-name :family 'ipv4 :service port-num :sentinel 'egrpc-sentinel :filter 'egrpc-filter :server 't)
and it works for me. So I don't know if the :host is interfering, or the lack of a :sentinel.
Marc
On Fri, Oct 2, 2009 at 9:14 AM, Marc Feeley feeley@iro.umontreal.ca wrote:
In my own experiments to get Gambit and emacs talking over TCP I have used this incantation:
(make-network-process :name process-name :buffer buffer-name :family 'ipv4 :service port-num :sentinel 'egrpc-sentinel :filter 'egrpc-filter :server 't)
and it works for me. So I don't know if the :host is interfering, or the lack of a :sentinel.
I figured it out. The Emacs server was using ipv6 and Gambit was using ipv4. I have to tell either one to use the correct one. In my case, adding ":family 'ipv4" or setting the host to "127.0.0.1" fixed it.
Thanks, James
Date: Fri, 2 Oct 2009 11:34:20 -0400 From: James Long longster@gmail.com
lack of a :sentinel.
I figured it out. The Emacs server was using ipv6 and Gambit was using ipv4. I have to tell either one to use the correct one. In my case, adding ":family 'ipv4" or setting the host to "127.0.0.1" fixed it.
There are three problems here:
1. GNU Emacs's MAKE-NETWORK-PROCESS (if it is GNU Emacs that you're using) fails to do the right thing with what getaddrinfo returns for `localhost': rather than opening listening sockets for all of the address info records returned, it chooses the first one that works, which happens to be for IPv6. This is a bug in GNU Emacs. Gambit probably has a similar bug.
2. Gambit's OPEN-TCP-CLIENT fails to use getaddrinfo, and instead uses the now ten-years deprecated gethostbyname. This means that it can't find correct information about a hostname: it will be limited to IPv4 socket addresses, and not, for example, IPv6 socket addresses. This has other bad consequences not related to IPv6; see, e.g., http://udrepper.livejournal.com/16116.html.
Not only this, but OPEN-TCP-CLIENT fails to do the right thing with the list of addresses returned by the ##OS-HOST-INFO procedure: rather than trying to connect to the addresses in sequence, using the first one that accepts the connection, it just chooses the first address in the list, whether or not that one works. This is a bug, or rather two, in Gambit.
3. Now you have sprinkled needless protocol-dependence in your code as a consequence of the interaction between these bugs in GNU Emacs and Gambit!
Although this is the wrong place to suggest fixing GNU Emacs, it would be nice if Gambit didn't exhibit these bugs. Fixing either GNU Emacs or Gambit in this case would solve jlongster's problem without requiring him to change any of his code!
Not only does getaddrinfo behave much better than gethostbyname, but it is easier to use, too. The getaddrinfo(3) man page on BSD systems shows how to use it both ways, for connecting sockets and listening sockets: http://netbsd.gw.com/cgi-bin/man-cgi?getaddrinfo. Observe that none of the code says anything about address/protocol families or particular kinds of sockaddr_* or *_addr structs: you just call getaddrinfo, and zip through the list of address info records, which tell you exactly what arguments you need to pass to the socket, bind, and connect system calls.