区分从socket.getInputStream()接收的消息

时间:2015-10-27 12:27:32

标签: android ios sockets

我有点问题,问题如下:

在服务器套接字处,服务器接收数据类型为字节数组:

this.receiveStream = new DataInputStream(this.clientSocket.getInputStream());
byte[] receiveBuffer = new byte[bufferSize];
while (this.receiveStream.read(receiveBuffer, 0, receiveBuffer.length) > -1) {
String dataReceive = new String(receiveBuffer, StandardCharsets.UTF_8).trim();
}

如果客户端在一个线程中发送文本消息,那么服务器运行良好,但如果客户端运行> = 2线程并发发送文本消息,那么在服务器上,消息是混合的,这意味着clientThead1发送" ABC&#34 ;,clientThead2发送" XYZ" =>服务器接收" AXBC"或" AXYZ",... =>这不是预期的消息。 如何解决这个问题???

P / S:我已经测试了服务器接收消息作为文本,它运行良好:

while (true) {
String dataReceive = this.receiveStream.readUTF().trim();
}

但我无法使用它,因为服务器服务多平台客户端,所以我想服务器使用字节数组来接收数据

全心全意,

更新 我无法发布完整的代码,因为它是非常长的字符

这是链接所有代码客户端+服务器https://www.mediafire.com/folder/j4d041uqfowt6/SocketApp

2 个答案:

答案 0 :(得分:0)

您使用TCP还是UDP?重要的是,插座不能掩盖差异。

对于TCP, 客户端线程不得重用相同的连接。

每个客户端线程必须打开自己的连接,就好像它是不同设备上的应用程序一样。

每次侦听套接字收到作业时,服务器都必须启动一个新线程。该线程将使用自己的连接;服务于不同客户端的线程是独立的,就好像它是不同设备上的应用程序一样。

我认为您看到了逻辑:一个客户端线程< - >一个服务主题。

(我想你知道监听套接字不接收数据,它会创建一个数据套接字。)

对于UDP,在服务器端,您必须自己区分客户端。 如果您发送单个字节,则不可能,但数据包不是单个字节,UDP数据包包括辅助信息。您拥有发件人的IP和端口,因此如果客户端不是在同一IP上使用相同端口的两个线程,则可以区分客户端。

答案 1 :(得分:0)

使用子线程从套接字和主线程读取数据以接受请求并移交给子..

服务器

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Server extends Thread {

    public Server(String ip, int port) {
        try {
            ServerSocket ser = new ServerSocket(port);
            System.out.println("Listening....");
            while (true) {
                Socket soc = ser.accept();
                new Child(soc).start();
                System.out.println("Child Started...");
            }

        } catch (IOException e) {
        }
    }

    private class Child extends Thread {

        Socket cSoc;

        public Child(Socket soc) {
            this.cSoc = soc;
        }

        @Override
        public void run() {
            try {
                String data = "";
                InputStream in = cSoc.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                int ch = 0, cnt = 0;
                byte[] buffer = new byte[1024];
                int length = Integer.parseInt(br.readLine());
                System.out.println("Message Length = " + length);
                while ((ch = in.read(buffer)) != -1) {
                    data += new String(buffer);
                    cnt += ch;
                    if (cnt >= length) {
                        break;
                    }
                }
                System.out.println("Message = " + data);
            } catch (IOException ex) {

            }

        }

    }

    public static void main(String[] args) {
        new Server("localhost", 1234).start();
    }
}

<强>客户端

import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class Client {

    public static void main(String[] args) {
        try {
            Socket s = new Socket("localhost", 1234);
            OutputStream o = s.getOutputStream();
            PrintStream ps = new PrintStream(o);
            String data = "your data";
            ps.println(data.length());
            Thread.sleep(100);
            o.write(data.getBytes());
            ps.close();
            o.close();

        } catch (Exception e) {
        }
    }
}

这只是一个可以包含概念的示例实现。