I have to write a program for a scenario in which a java program will communication to the TCL program using socket programming. I have successfully tried the socket programming for TCL and Java individually. But as I have to have a Java program as a client socket and TCL program as a server, I am not able to do it successfully.
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
// 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, server shows nothing.
I started the client, server shows "Accepted connection from at Mon May 6 02:50:21 PDT 2013" and the client shows "Connecting to on port 9999 Just connected to /(server ip address):9999"
As the out.writeUTF is executed in client, server shows "The packet from the client is "Hello from : /<client ip address>:<client port no>". But nothing is shown at client as it is supposed to show the reply from the server. The client process does not exit and waits for the execution of System.out.println("Server says " + in.readUTF());.
Can someone please help here and tell why the client is not able to see the reply from the server when the connection is there, and client can send data to the server.
Thanks
Your Java client is using DataOutputStream.writeUTF and DataInputStream.readUTF; these use a simple framing protocol on top of the socket, which that Tcl server doesn't speak. This makes things go wrong.
The framing protocol is pretty simple. First, the length of the string (in bytes) is written as a two-byte big-endian ("network-endian") integer. Then the UTF-8 bytes of the string are sent. Pretty straight-forward, but you need to know in order to actually handle it right. You also want to put the socket in binary mode when working this way; you're not using a line-oriented protocol any more.
# 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With