繁体   English   中英

在android套接字中:在服务器中仅接收到array []的一部分,套接字中是否有最大大小?

[英]in android socket: in the server only part of the array[] is received, is there a max size in socket?

我在android和服务器c#1-中开发了clint,当我将小字符串作为“ hello world”发送时,它已成功发送到服务器,并且客户端也从服务器收到了响应msg

2-现在,我尝试从android发送大字符串(实际上是图像表示形式),字符串msg的大小为23.000字节。 大字符串的问题是:

1- the server c# did not receive  all the string bytes 
2- the response Msg did not received to the client

两个实验中的代码都相同 ,只是字符串大小不同,请告诉我

这是客户端android JAVA唯一的连接功能:public void ConnectToServer(){

    Thread ConnectToClient = new Thread(new Runnable() {

        @Override
        public void run() {try {
            Log.e("MESSAGE", "HERE void run");

            // time start here
            Log.e("MESSAGE", "Start time");
            long startTime = System.nanoTime();

            //Connect to socket 
            Log.e("MESSAGE", "HERE socket object");
            socket = new Socket(HOST, PORT);
              Log.e("MESSAGE", String.valueOf(client_str));
                        client_str = “hellow world”; //the problem if this string is huge i cannot write the string here it is too long


            DataOutputStream output_to_server = new DataOutputStream(socket.getOutputStream());
            output_to_server.writeBytes(client_str);
            output_to_server.flush();
               //receive ACK from (server)
                                        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    Log.e("MESSAGE", "Recieve the ACK from server");
                    recievedMsg = in.readLine();

                    Log.e("MESSAGE", String.valueOf(recievedMsg));

            //Update TextView
            Message msg = null;
            msg = textview_handler_thread.obtainMessage();
            msg.obj = recievedMsg;
            textview_handler_thread.sendMessage(msg);

        } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
    ConnectToClient.start();
}

这是c#服务器:

   namespace CloudLet1Code
{
public static class Program
{
    public static void Main(string[] args)
    {
        IPAddress ipAdress = IPAddress.Parse("192.168.1.4");

            // Initializes the Listener
        TcpListener listener = new TcpListener(ipAdress, 4003);
        // Start Listeneting at the specified port
        listener.Start();

        Console.WriteLine("Server running - Port: 4003");
        Console.WriteLine("Local end point:" + listener.LocalEndpoint);
        Console.WriteLine("Waiting for connections...");

        Socket s = listener.AcceptSocket();
        // When accepted
        Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);
        byte[] b = new byte[1000000];
        string rcvd_msg = null;        
        int k = s.Receive(b);
        Console.WriteLine("Recieved...\n");

         for (int i = 0; i < k; i++)
         {
              Console.Write(Convert.ToChar(b[i]));
             rcvd_msg += Convert.ToChar(b[i]).ToString();
         }
        Console.WriteLine("\nrcvd_msg = " + rcvd_msg);
        listener.Stop();
        Console.WriteLine("Automatic message sent!");

        ///send ack
        ASCIIEncoding asen = new ASCIIEncoding();
        s.Send(asen.GetBytes("The string was recieved by the server number 1."));
        Console.WriteLine("\nSent Acknowledgement");
        // ack sent 
        s.Close();

    }
}

}更新代码(c#)..接收数据块,但仍无法提取字符串:

public static class Program
{
    public static void Main(string[] args)
    {
        IPAddress ipAdress = IPAddress.Parse("192.168.1.2");

        // Initializes the Listener
        TcpListener listener = new TcpListener(ipAdress, 4003);
        // Start Listeneting at the specified port
        listener.Start();

        Console.WriteLine("Server running - Port: 4003");
        Console.WriteLine("Local end point:" + listener.LocalEndpoint);
        Console.WriteLine("Waiting for connections...");

        Socket s = listener.AcceptSocket();
        // When accepted
        Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);


        MemoryStream bufferStream = new MemoryStream();
        byte[] buffer = new byte[1024];
        int count;
        //keep reading blocks from stream until there is no more data received
        //receive will block until there is data or the end of the stream has been reached
        while((count = s.Receive(buffer))!=0)
        {
            //write all received bytes into buffer stream ( which is in memory byte stream)
            bufferStream.Write(buffer, 0, count);
        }
        //get the entire brte array from the stream
        byte[] entireData = bufferStream.ToArray();
        //convert the received data to string using ascii incoding 
        String ReceivingDataString = System.Text.Encoding.ASCII.GetString(entireData);


        Console.WriteLine("Automatic message sent!");

        ///send ack

        ASCIIEncoding asen = new ASCIIEncoding();
        s.Send(asen.GetBytes("The string was recieved by the server number 1."));
        Console.WriteLine("\nSent Acknowledgement");
        // ack sent 
        s.Close();


    }

我猜问题出在int k = s.Receive(b); 在您的C#应用​​程序中。 这是因为这么大的数据块不一定会在1个数据包中到达,这意味着在调用Socket.Receive()流的整个主体将不可用。 您可以尝试将其循环放置,并继续读取所有数据,直到没有可用数据为止(流的末尾)。 看看https://msdn.microsoft.com/zh-cn/library/8s4y8aff(v=vs.110).aspx ,尤其是底部的备注:

“如果使用的是面向连接的套接字,那么Receive方法将读取尽可能多的数据”

这就是说,如果有任何可用数据,它将立即返回该数据-在返回所有可用数据并将其加载到缓冲区之前,它不会等待流结束(因为该流的长度可能为千兆字节,并且可能不会适合内存)。 以下示例显示了一个快速示例,说明如何开始实现分块接收数据并将其缓冲到MemoryStream中。

Socket s = yoursocket;
MemoryStream bufferStream = new MemoryStream();
byte[] buffer = new byte[1024];
int count;
// Keep reading blocks from the stream until there is no more data being received.
// As specified in the docs, Receive will block until there is data - or the end of the
// stream has been reached.
while((count = s.Receive(buffer)) != 0)
{
    // Write all received bytes into the buffer stream
    // (which is an in memory byte stream)
    bufferStream.Write(buffer, 0, count);
}

// Get the entire byte array from the stream
byte[] entireData = bufferStream.ToArray();

// Convert the received data to a string using ascii encoding
string receivedDataAsString = System.Text.Encoding.ASCII.GetString(entireData);

附带说明一下,由于您发送图像时,不应使用文本编码(例如ASCII编码),但这与阻止一次性接收所有数据的实际问题无关。 我希望这能使您对如何解决问题有所了解。

编辑:Socket.Receive()在远程对等端结束流之前不会返回0。 不发送更多数据并不构成流的结尾。 因此,为了使上面的示例循环( while((count = s.Receive(buffer)) != 0)发生中断,您的远程对等while((count = s.Receive(buffer)) != 0)需要完全关闭流。(使用DataOutputStream.close()另外,您还需要捕获Socket。引发的一些异常,并根据不同的情况接收远程对等方在断开连接的情况下(例如,超时)。如果您想处理数据而不必等待流关闭,您将需要在数据到达时使用它-在我的示例中,直接在while循环内。

while((count = s.Receive(buffer)) != 0)
    {
        // Convert the current buffer to a string (using the number of read bytes as the length of this string)
        string newText = System.Text.Encoding.ASCII.GetString(buffer, 0, count);
       //Console.WriteLine($"New data received: {newText}");
    }

is to ... 我对您的最佳建议是...

... 停止! ...

objective” here (and, therefore, “your immediate problem,”) is: “to succeed in sending 23KB by means of a socket.” 您在这里的目标”(因此也就是“您的直接问题”)是:“通过套接字成功发送23KB”。

在这一点上,您“正在做一个已经完成了数千次的工作。”实际上,您正在发明一个完整的 you are now doing, “it has already been done before.” STOP and look for which already knows how to solve this problem for you. 当然,这完全没有必要,因为您现在在做什么,“它已经完成了。” 停下来 ,寻找已经知道如何为您解决该问题的 you can find it.) (您将需要解决许多错误。因此,随时可以在可以找到它的捕获已经调试过的代码。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM