Go Back   AC3D Forums > Technical > AC3D Developers
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply
 
Thread Tools Display Modes
Old 24th October 2003, 05:05 PM   #1
Dennis
Senior Member
Professional user
 
Dennis's Avatar
 
Join Date: Jul 2003
Posts: 899
Default Sockets

I'm developing a program that allows me to change the "data" (text) field in AC3D objects from an external program while AC3D is running.

I'm using the AC3D socket support for this, connecting via Win32 sockets.

The first time I create a socket connection to AC3D, I'm fine. If I close the connection then re-open it from my client, however, AC3D is no longer listening on the port, and I have to restart AC3D to establish a connection again.

Is there a way I can re-establish a connection without restarting AC3D? Or is there a special way I need to disconnect the socket before I re-open it?

Thanks,
Dennis
Dennis is offline   Reply With Quote
Old 25th October 2003, 02:52 AM   #2
Andy
Administrator
Professional user
 
Andy's Avatar
 
Join Date: Jun 2003
Posts: 4,563
Default Re: Sockets

Hi Dennis, I haven't looked at this for a long time but the code that handles the socket stuff is in tcl/ac3d.tcl starting with 'proc get_cmd'.

Let me know if you work it out.

Andy
Andy is offline   Reply With Quote
Old 25th October 2003, 02:00 PM   #3
Dennis
Senior Member
Professional user
 
Dennis's Avatar
 
Join Date: Jul 2003
Posts: 899
Default Re: Sockets

Hmm - this may have been some screwiness in my system --- these symptoms aren't coming up again. I can re-establish connections as often as I like now.

The only thing that's changed is my system's been rebooted - the machine must've been tired ....

Thanks!
Dennis
Dennis is offline   Reply With Quote
Old 25th October 2003, 04:22 PM   #4
Dennis
Senior Member
Professional user
 
Dennis's Avatar
 
Join Date: Jul 2003
Posts: 899
Default Re: Sockets

Spoke too soon - started happening again after a little while. I ended up looking at the ac3d.tcl code after all - by the way, it's a very clean implementation, with sensible function names and easy-to-follow logic - it's almost self documenting.

I traced the problem down to the socket #'s being grabbed. I was alternating between socket 400 and 412 when I established a connection. However, if I grabbed the same socket twice in a row, AC3D closed it immediately the second time.

I found this code in ac3d.tcl:

Code:
proc do_connection {sock ip port} {

	fileevent $sock readable "get_cmd $sock"
	puts "New socket connected to AC3D (socket id $sock, remote ip:port $ip:$port)"

	close_current_command_socket
	set_command_socket $sock
}
When I make a second connection against a running AC3D session, and let's say I grab the same socket number as the last connection I made (412 in this example), do_connection issues a "close_current_command_socket" to close the last socket it remembers (which, in this case, is still 412). So it closes the socket immediately after it opens the new one.

I was able to fix this by editing my copy of ac3d.tcl to pass the new socket number to close_current_command_socket, then changing the logic to only close the old one if it was a different socket. This allows me to grab the same socket twice in a row w/o getting it clipped by close_current_command_socket.

fyi, I also tried the sample ac3dshell.tcl --- it seems to work fine, since the ac3dshell.tcl doesn't close the socket when it's done (it lets AC3D do it). In my own app, I allow the socket to be opened and closed.

I ended up changing 4 lines of code across three functions. The changes I made in my file are as follows (see comments):

Code:
proc do_connection {sock ip port} {

	fileevent $sock readable "get_cmd $sock"
	puts "New socket connected to AC3D (socket id $sock, remote ip:port $ip:$port)"

	# DH - Added $sock parameter
	close_current_command_socket $sock
	set_command_socket $sock
}
Code:
proc disable_socket_commands {} {

	global listensock

	if { $listensock != 0 } {

		# DH - Added 0 parameter
		close_current_command_socket 0

		set err [catch { close $listensock }]
		set listensock 0
	}

	puts "Command socket connections disabled"
}
Code:
# DH - Added "sock" argument, which is the currently open socket
#         (sock == 0 if we want to force a close).
#      This allows close_current_command_socket to compare the old
#      socket (the one it's trying to close) against the new socket,
#      in the event a function like "do_connection" cleans up the
#      old socket first.
proc close_current_command_socket { sock } {

	global rsock

        # DH - added "&& $rsock != $sock"
	if { $rsock != 0 && $rsock != $sock } {
		set err [catch { close $rsock }]
		puts "tcl socket $rsock disconnected by AC3D"
		set rsock 0
	}
}
In all, a quick and easy fix (whew!).

I'm not sure how often this feature of AC3D gets used, but I'm *really* glad it's there. So far, it's allowing me to write a fairly robust property editor with my own GUI (so I'm not so dependent on TCL, with which I'm not terribly adept).

Thanks,
Dennis
Dennis is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



All times are GMT -4. The time now is 05:41 PM.


AC3D Forum
(C) Inivis Limited 2020