Java和TCL之间的套接字编程 [英] Socket programming between Java and TCL

查看:25
本文介绍了Java和TCL之间的套接字编程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须为一个场景编写一个程序,在这个场景中,Java 程序将使用套接字编程与 TCL 程序进行通信.我已经成功地分别尝试了 TCL 和 Java 的套接字编程.但是由于我必须有一个 Java 程序作为客户端套接字和 TCL 程序作为服务器,所以我无法成功.

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

// 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();
      }
   }
}

  1. 我启动了服务器,服务器什么也没显示.

  1. I started the server, server shows nothing.

我启动了客户端,服务器显示Accepted connection from at Mon May 6 02:50:21 PDT 2013"​​;和客户端显示"连接到端口 9999刚刚连接到/(服务器ip地址):9999"

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"

由于 out.writeUTF 在客户端执行,服务器显示来自客户端的数据包是 "Hello from :/:";. 但是客户端没有显示任何内容,因为它应该显示来自服务器的回复.客户端进程不退出,等待System.out.println("Server say " + in.readUTF());的执行.

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.

谢谢

推荐答案

您的 Java 客户端正在使用 DataOutputStream.writeUTFDataInputStream.readUTF;这些在套接字顶部使用一个简单的成帧协议,Tcl 服务器不使用它.这会让事情出错.

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.

帧协议非常简单.首先,字符串的长度(以字节为单位)被写成一个两字节的大端(网络端")整数.然后发送字符串的 UTF-8 字节.非常简单,但你需要知道才能真正正确地处理它.以这种方式工作时,您还希望将套接字置于二进制模式;您不再使用面向行的协议.

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

这篇关于Java和TCL之间的套接字编程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆