【问题标题】:TCP: How to get response from Vb.net server in Android Client?TCP:如何从 Android 客户端中的 Vb.net 服务器获取响应?
【发布时间】:2015-05-11 00:21:46
【问题描述】:

这不可能是重复的。本网站上的任何答案都无法充分回答或解决我的问题。

我正在尝试通过 TCP 套接字连接到 VB.NET 服务器并在 Android 应用程序中获得响应。响应始终为 null 作为字符串或 -1 作为字节。

我必须连接多个平台并获得响应,但目前我只想专注于 Android 应用。或许我想通了,往其他平台前进会更容易。

我无权编辑 VB.NET 实时服务器中的任何代码。那里的系统很旧,到目前为止只向其他 Windows 客户端发送响应。

这是我的 Android 客户端。它位于从 mainActivity 调用的后台任务中。下面的命令字符串应该以字符串的形式从服务器返回坐标。没有返回任何内容。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {


    public static void sendMessage() throws IOException, InterruptedException {

        Socket socket = null;
        String host = "";
        int port = ;
        PrintStream stream = null;
        String command="";

        try {
            Socket s = new Socket(host,port);
            System.out.println("Socket created");

            //outgoing stream redirect to socket
            OutputStream out = s.getOutputStream();

            PrintWriter output = new PrintWriter(out);
            output.println(command);
            output.flush();
            System.out.println("command sent");
            BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));

            //read line(s)
            System.out.println("Getting response:");
            String st = input.readLine();
            System.out.println("Response : " + st);
            //Close connection
            s.close();
        }

        catch (UnknownHostException e) {
            System.out.println("Don't know about host : " + host);
            e.printStackTrace();
            System.exit(1);
        }

        catch (IOException e) {
            System.out.println("Couldn't get I/O for the connection to : " + host);
            e.printStackTrace();
            System.exit(1);
        }

    }
}

一位开发人员还给我发了一个 VB 测试客户端,它可以毫无问题地连接、发送和接收

这是开发人员发送给我的一类 VB:NET 虚拟服务器项目,以了解实时服务器是如何设置代码的。我可以看到它将字符串作为 unicode 获取,但我对 VB 不知道我的 Java 代码哪里出错了。

当我打开项目并在 localhost 上启动服务器时,无论如何我都无法从 java 客户端连接到它。然后我用 PHP 编写了另一个客户端,同样的问题,连接建立但没有响应。我下载了一个socket tester软件,但它也可以连接但没有得到响应。

Option Explicit On
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports Microsoft.VisualBasic

Imports System.Net.Dns
Imports System.Text.UnicodeEncoding
Imports System.Threading
Imports System.Data.SqlClient



Public Enum glenConnectionType
    ConstantConnection = 1
    ConnectOnDemand = 2
    AsyncConnection = 3
End Enum

Public Class clsDynaListner
    Public tcpServer As Socket
    Public tcpClient As Socket
    Public tcpPort As Integer
    Public tcpBilnr As Integer ' was shared SHOULD PROB BE INITIALISED TO 0
    Public ThreadClient As Thread
    Public LastKontakt As Date = Nothing
    Public ConActive As Boolean = False
    Private tcpClientEndPoint As System.Net.IPEndPoint
    Private bCommandLength(15), bReplyLength(15) As Byte
    Private iCommandLength, iReplyLength As Integer
    Private sReplyLength As String
    Private sCommand, sReply As String
    Private theCommandBytes() As Byte
    Private theReplyBytes() As Byte
    Private Const AsyncMaxBytes As Integer = 600000 '1024
    Public Shared AsyncData As String = Nothing

    Public Sub New(ByVal currentTCPPort As Integer, ByVal theConnectionType As glenConnectionType)
        tcpPort = currentTCPPort
        tcpClientEndPoint = New System.Net.IPEndPoint(System.Net.IPAddress.Any, tcpPort)

        'Select Case theConnectionType
        '    Case glenConnectionType.ConstantConnection
        '        ThreadClient = New Threading.Thread(AddressOf ListenForConstantConnection)
        '    Case glenConnectionType.ConnectOnDemand

        ThreadClient = New Threading.Thread(AddressOf ListenForConnectOnDemand)

        '    Case glenConnectionType.AsyncConnection
        'ThreadClient = New Threading.Thread(AddressOf ListenForAsyncConnection)
        'End Select

        ThreadClient.Start()
    End Sub


Private Sub ListenForConnectOnDemand()
        While (True)
            Try
                tcpServer = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
                tcpServer.SendBufferSize = TCP_BUFFER_SIZE
                tcpServer.ReceiveBufferSize = TCP_BUFFER_SIZE
                tcpServer.Blocking = True
                tcpServer.Bind(tcpClientEndPoint)
                tcpServer.Listen(0)
                tcpClient = tcpServer.Accept

                tcpClient.SendBufferSize = TCP_BUFFER_SIZE
                tcpClient.ReceiveBufferSize = TCP_BUFFER_SIZE

                ' Find out how big the command is going to be
                tcpClient.Receive(bCommandLength)
                iCommandLength = CType(Unicode.GetString(bCommandLength), Integer)

                ' Bring that command to daddy
                Array.Resize(theCommandBytes, iCommandLength + 1)
                tcpClient.Receive(theCommandBytes)
                sCommand = Unicode.GetString(theCommandBytes)
                gInMessage = sCommand

                ' Get the reply
                sReply = "Response:"
                gOutMessage = sReply

                ' Inform the controller of the length of the reply transmission
                iReplyLength = (sReply.Length * 2) - 1
                sReplyLength = iReplyLength.ToString.PadLeft(8, "0")
                bReplyLength = Unicode.GetBytes(sReplyLength)
                tcpClient.Send(bReplyLength)

                ' Send the reply data
                Array.Resize(theReplyBytes, iReplyLength + 1)
                theReplyBytes = Unicode.GetBytes(sReply)
                tcpClient.Send(theReplyBytes)

                Array.Clear(theCommandBytes, 0, theCommandBytes.Length)
                Array.Clear(theReplyBytes, 0, theReplyBytes.Length)

                tcpClient.Close()
                tcpServer.Close()
                tcpClient = Nothing
                tcpServer = Nothing

            Catch ex1 As Exception
                Try
                    tcpClient.Close()
                    tcpServer.Close()
                    tcpClient = Nothing
                    tcpServer = Nothing
                    ' ErrMessage = "LisForContr :" & tcpPort.ToString & ex1.Message
                Catch
                End Try
            End Try
        End While

    End Sub

    Protected Overrides Sub Finalize()
        Try
            tcpServer.Close()
            ThreadClient.Abort()
        Catch
        End Try

        MyBase.Finalize()
    End Sub

End Class

我一直在研究这个问题。我构建的应用程序适用于 PHP Web App、Android Native 和 iPhone Native。问题只是从 VB 服务器获得响应。

希望有人帮助我朝着正确的方向前进。

我还向开发人员询问了响应是否有换行符。它没有,而且似乎他们愿意弄乱代码,因为它在那里服务了很多年。所以我必须设法解决这个问题。

如果您需要我提供更多信息,请询问。

【问题讨论】:

  • 如果我没记错的话,你确实需要一个while(true) 并无限地收听 InputStream。因此,每当您获得一些信息时,它都会被自动读取。
  • 感谢您的意见。我会试试的
  • this.
  • 尝试了你的建议。没有喜悦。将查看您现在发送的链接。
  • 很遗憾,该链接没有帮助。

标签: java android vb.net tcp tcpclient


【解决方案1】:

要从 Java 发送到 VB.NET 服务器,您必须将字符串作为 unicode 字节发送。首先发送期望字节的长度,然后发送主要数据并刷新。您必须确切地知道服务器期望什么,以便相应地格式化和编码数据以准备发送它。

在调试 VB 客户端和服务器后,我能够成功解决我的问题。此客户端将处理字节数组、流式传输高级 sql 命令并获取响应。更新将获取 xml 表数据。任何想输入如何让这个客户变得更好的人。不客气。

更新了我的java客户端如下。

/**
 * MR-TCP Java & VB.NET DataExchange Client 0.95 - Maze Runner 2015
 */

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class Client {

    public static String sendCommand(String commandString, Boolean IsID) throws IOException, InterruptedException {

        String host;
    int port;
    String command;
    byte[] commandBytes;
    String commandLength;
    byte[] cmdLengthBytes;
    Socket s;
    DataOutputStream stream;
    String dataString = "";

    host = ""; //
    port = 0; // 

    command = commandString;
    commandBytes = command.getBytes("UTF-16LE"); // returns byte[18]

    if(IsID){
        commandLength = "00000021";
        cmdLengthBytes = commandLength.getBytes("UTF-16LE"); 
    } else {
        String iCommandLength = command; // Get the command length
        cmdLengthBytes = iCommandLength.getBytes("UTF-16LE");
        int commandNewLength = cmdLengthBytes.length-1;
        String newLength = "0000" + String.valueOf(commandNewLength);
        cmdLengthBytes = newLength.getBytes("UTF-16LE");

    }

    try {
        s = new Socket(host, port); // Connect to server

        //Send the command to the server
        stream = new DataOutputStream(s.getOutputStream()); // get ready to send

        stream.write(cmdLengthBytes); // tell the server how many bytes to expect

        System.out.println("Command length sent");

        stream.write(commandBytes); // Send the command to papa...

        stream.flush(); // guaranteed sending

        System.out.println("Command sent");

        //Receive the command from the server.
        DataInputStream is = new DataInputStream(s.getInputStream()); // get ready to receive

        ByteArrayOutputStream buffer = new ByteArrayOutputStream(); // prepare to get array

        int nRead;
        byte[] data = new byte[1024];

        while ((nRead = is.read(data, 0, data.length)) != -1) { // read the array byte by byte
            buffer.write(data, 0, nRead);
        }

        byte[] dataBytes =  buffer.toByteArray(); // get complete array

        dataString = buffer.toString("UTF-16LE").substring(8); // get rid of the array length and convert to string


        stream.close(); // close the dataStream

        s.close(); // close the connection

        System.out.println("Disconnected");

    } catch (IOException e){
        e.printStackTrace();
    }

    System.out.println("Function Complete");

    System.out.println("Server response:" + dataString);


    return dataString;

    }
}

【讨论】:

  • 好的。做得好。我今天才看到你的回答。它看起来很像我尝试过的。你把服务器关闭了,我看到了。嗯,我能理解。
  • 我的申请取得了巨大的成功。我还使用我的答案中提到的相同原则在我的 PHP Web 应用程序上取得了成功。我现在还可以通过这两个应用程序解析 xml 数据。感谢您的支持。
猜你喜欢
  • 1970-01-01
  • 2018-12-30
  • 1970-01-01
  • 1970-01-01
  • 2018-12-02
  • 2022-01-05
  • 1970-01-01
  • 2021-05-06
  • 2013-02-17
相关资源
最近更新 更多