Socket programming between Java and TCL
I have to write a program for a scenario in which a java program will communicate with a TCL program using socket programming
TCL program of server
set svcPort 9999 #Implement the service # This example just writes the info back to the client... proc doService {sock msg} { puts $sock "$msg" } # Handles the input from the client and client shutdown proc svcHandler {sock} { set l [gets $sock] ;# get the client packet puts "The packet from the client is $l" if {[eof $sock]} { ;# client gone or finished close $sock ;# release the servers client channel } else { doService $sock $l } } # Accept-Connection handler for Server. # called When client makes a connection to the server # Its passed the channel we're to communicate with the client on,# The address of the client and the port we're using # # Setup a handler for (incoming) communication on # the client channel - send connection Reply and log connection proc accept {sock addr port} { # if {[badConnect $addr]} { # close $sock # return # } # Setup handler for future communication on client socket fileevent $sock readable [list svcHandler $sock] # Read client input in lines,disable blocking I/O fconfigure $sock -buffering line -blocking 0 # Send Acceptance string to client puts $sock "$addr:$port,You are connected to the echo server." puts $sock "It is Now [exec date]" # log the connection puts "Accepted connection from $addr at [exec date]" } # Create a server socket on port $svcPort. # Call proc accept when a client attempts a connection. socket -server accept $svcPort vwait events ;# handle events till variable events is set
and
Java client program
// File Name GreetingClient.java import java.net.*; import java.io.*; public class GreetingClient { public static void main(String [] args) { String serverName = args[0]; int port = Integer.parseInt(args[1]); try { System.out.println("Connecting to " + serverName + " on port " + port); Socket client = new Socket(serverName,port); System.out.println("Just connected to " + client.getRemoteSocketAddress()); OutputStream outToServer = client.getOutputStream(); DataOutputStream out = new DataOutputStream(outToServer); out.writeUTF("Hello from " + client.getLocalSocketAddress()+"\n"); InputStream inFromServer = client.getInputStream(); DataInputStream in = new DataInputStream(inFromServer); System.out.println("Server says " + in.readUTF()); client.close(); }catch(IOException e) { e.printStackTrace(); } } }
>I started the server and the server didn't show anything. > I started the client, and the server displayed "accept connection from PDT 2013 at 02:50:21, Monday, May 6, 2013", The client displays "connect to port 9999 just connected to / (server IP address): 9999" > when out.writeutf is executed on the client, the server displays "the packet from the client is" Hello from: / < client IP address >: < client port no > ". however, the client does not display anything because it should display the reply from the server. The client process does not exit and waits for the execution of system.out.println (" the server says "in. Readutf())
Someone can help here and explain why the client can't see the reply from the server when connecting. The client can send data to the server
thank you
Solution
Your Java client is using dataoutputstream Writeutf and datainputstream readUTF; These use simple framing protocols on sockets that the TCL server won't say This will make things go wrong
The framework agreement is very simple First, the length of the string (in bytes) is written as a double byte network endian integer Then send UTF - 8 bytes of the string It's very simple, but you need to know to really handle it correctly You also want to put sockets in binary mode in this way; You no longer use line - oriented protocols
# Two helper procedures that kNow how to do the framing encoding/decoding proc writeJavaUTF {sock msg} { set data [encoding convertto utf-8 $msg] puts -nonewline $sock [binary format "S" [string length $data]]$data } proc readJavaUTF {sock} { binary scan [read $sock 2] "S" len set data [read $sock [expr {$len & 0xFFFF}]] return [encoding convertfrom utf-8 $data] } # This is your sample code,stripped of comments and adapted set svcPort 9999 proc doService {sock msg} { writeJavaUTF $sock "$msg"; # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } proc svcHandler {sock} { set l [readJavaUTF $sock]; # <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< puts "The packet from the client is $l" if {[eof $sock]} { close $sock } else { doService $sock $l } } proc accept {sock addr port} { fileevent $sock readable [list svcHandler $sock] # Next *three* lines are changed! fconfigure $sock -buffering line -blocking 0 -translation binary writeJavaUTF $sock "$addr:$port,You are connected to the echo server." writeJavaUTF $sock "It is Now [exec date]" puts "Accepted connection from $addr at [exec date]" } socket -server accept $svcPort vwait events