简体   繁体   English

套接字Java上的图像

[英]Image over socket Java

Im having a problem getting my server to send image over a socket. 我在让我的服务器通过套接字发送图像时遇到问题。 I need to have 10 1920x1080 images sent to the client in a timecrunch of atleast 5-10 seconds. 我需要在至少5-10秒的时间间隔内将10张1920x1080图像发送给客户端。 I seem to get an error anywhere I go or my client/server failsafes go off and make it impossible to send in those certain ways. 我似乎在任何地方都遇到错误,或者我的客户端/服务器故障保护失效并且无法以某些特定方式发送。 Could anyone point me in the right direction and tell me a way to implement this without messing up other proccesses? 有人能指出我正确的方向,并告诉我一种实现此目标而又不弄乱其他过程的方法吗?

Client code for nonobject things, and used for UTF packets. 非对象事物的客户端代码,用于UTF数据包。

 DataInputStream in ;
 Client client;
public boolean enabled = true;
 Object packet;
 String[] tempData;
public Thread thread;

public Data(DataInputStream in , Client client) {
    this. in = in ;
    this.client = client;
}

@
Override
public void run() {
    while (enabled) {
        int x = 0, y = 0, width = 0, height = 0, r = 0, g = 0, b = 0, id = 0, mousex = 0, mousey = 0, alpha = 0;
        String data = "Invalid";
        try {
            data = in.readUTF().trim();
        } catch(Exception e){
            client.comp.printErr("Disconnected from server, " + e.toString());
            client.disconnectClient("Socket Closed.");
            enabled = false;
        }
        try{

            if (data.contains("id/")) {
                data = data.split("id/")[1];
                client.id = Integer.valueOf(data);
                client.serverHasResponded = true;
                client.comp.printOut("Client ID: " + data);
            }
            if (data.contains("rejected/")) {
                data = data.split("rejected/")[1];
                //Check to see if server sent packet info;
                packet = "null";
                try {
                    if (data.contains("/")) {
                        tempData = data.split("/");
                        data = tempData[0];
                        packet = "null";
                        for (int i = 1; i < tempData.length; i++) {
                            if (!packet.equals("null")) {
                                packet = packet + "/" + tempData[i];
                            } else packet = tempData[i];
                        }
                    }
                    // Packet info done.
                } catch (Exception e) {
                    client.comp.printErr("Error while splitting packet: " + e.toString());
                }
                if (Integer.valueOf(data) == 0) {
                    client.disconnectClient("No Slots Open.");
                    client.comp.printErr("Rejected from server, no slots open.");
                    enabled = false;
                }
                if (Integer.valueOf(data) == 1) {
                    client.disconnectClient("Invalid Version.");
                    client.comp.printErr("Rejected from server, invalid version.");
                    enabled = false;
                }
                if (Integer.valueOf(data) == 2) {
                    client.disconnectClient("Kicked.");
                    client.comp.printErr("Rejected from server, kicked.");
                    enabled = false;
                }
                if (Integer.valueOf(data) == 3) {
                    client.disconnectClient("Unknown Packet.");
                    client.comp.printErr("Rejected from server, client sent unknown packet on connection? Packet: " + packet);
                    enabled = false;
                }
                if (Integer.valueOf(data) == 4) {
                    client.disconnectClient("Already Logged in.");
                    client.comp.printErr("Rejected from server, the username " + client.comp.username + " is already logged on?");
                    enabled = false;
                }
                if (Integer.valueOf(data) == 5) {
                    client.disconnectClient("Not Authenticated");
                    client.comp.printErr("Rejected from server, server requires authentication and were not authenticated?");
                    enabled = false;
                }
                if (Integer.valueOf(data) == 6) {
                    client.disconnectClient("No tick from client.");
                    client.comp.printErr("Rejected from server, server didnt recieve a tick?");
                    enabled = false;
                }
                if (Integer.valueOf(data) == 7) {
                    client.disconnectClient("No open Canvases.");
                    client.comp.printErr("Rejected from server, all canvases blacklisted?");
                    enabled = false;
                }
                if (Integer.valueOf(data) == 8) {
                    client.disconnectClient("Banned.");
                    client.comp.printErr("Rejected from server, Banned.");
                    enabled = false;
                }
            }

            if(data.contains("servertick/")){
                data = data.split("servertick/")[1];
                if(Integer.valueOf(data) == client.id){
                    client.heartbeatManager.serverTicked();
                } else {
                    client.comp.printErr("Server sent an invalid tick.");
                }
            }

            if(data.contains("changeCanvas/")){
                data = data.split("changeCanvas/")[1];
                client.currentCanvas = Integer.parseInt(data);
            }

            if(data.contains("changeCanvasFailed/")){
                data = data.split("changeCanvasFailed/")[1];
                client.popups.add(new Popup(client, "Error", "Access denied to canvas "+data+"."));
            }

            if(data.contains("overrideChangeCanvas/")){
                data = data.split("overrideChangeCanvas/")[1];
                client.currentCanvas = Integer.parseInt(data);
                client.comp.printOut(data);
            }

            if(data.contains("broadcastToClient/")){
                data = data.split("broadcastToClient/")[1];
                client.chat.addChatMessage(data, Color.white);
            }

            if (data.contains("chatmessage/")) {
                data = data.split("chatmessage/")[1];
                String[] tokens = data.split("/");
                String user = "";
                String message = "";
                for (int i = 0; i < tokens.length; i++) {
                    if (i == 0)
                        user = tokens[0];
                    if (i == 1)
                        message = tokens[1];

                }
                client.chat.addChatMessage(user + ": " + message, Color.white);
            }

            if (data.contains("drawcircle/")) {
                data = data.split("drawcircle/")[1];
                String[] tokens = data.split("/");
                for (int i = 0; i < tokens.length; i++) {
                    if (i == 0)
                        x = Integer.valueOf(tokens[i]);
                    if (i == 1)
                        y = Integer.valueOf(tokens[i]);
                    if (i == 2)
                        width = Integer.valueOf(tokens[i]);
                    if (i == 3)
                        height = Integer.valueOf(tokens[i]);
                    if (i == 4)
                        r = Integer.valueOf(tokens[i]);
                    if (i == 5)
                        g = Integer.valueOf(tokens[i]);
                    if (i == 6)
                        b = Integer.valueOf(tokens[i]);
                    if (i == 7)
                        id = Integer.valueOf(tokens[i]);
                    if (i == 8)
                        alpha = Integer.valueOf(tokens[i]);
                }
                client.canvas[id].draw(x, y, width, height, r, g, b, alpha);
            }

            if (data.contains("erasecircle/")) {
                data = data.split("erasecircle/")[1];
                String[] tokens = data.split("/");
                for (int i = 0; i < tokens.length; i++) {
                    if (i == 0)
                        x = Integer.valueOf(tokens[i]);
                    if (i == 1)
                        y = Integer.valueOf(tokens[i]);
                    if (i == 2)
                        width = Integer.valueOf(tokens[i]);
                    if (i == 3)
                        height = Integer.valueOf(tokens[i]);
                    if (i == 7)
                        id = Integer.valueOf(tokens[i]);
                }
                client.canvas[id].erase(x, y, width, height);
            }

            if (data.contains("playerjoin/")) {
                data = data.split("playerjoin/")[1];
                client.chat.addChatMessage(data+" has joined the game.", Color.yellow);
            }

            if (data.contains("playerleave/")) {
                data = data.split("playerleave/")[1];
                client.chat.addChatMessage(data+" has left the game.", Color.yellow);
            }

        } catch (Exception e) {
            client.comp.printErr("Failed to process a packet, " + e.toString());
        }

    }
}

public void close() throws Exception{
    thread.stop();
    enabled = false;
}

public void setThread(Thread t){
    thread = t;
}

Client code ment for images (not modified yet) : 图像的客户端代码(尚未修改):

    Client client;
DataInputStream in;
Thread thread;

public DataObjects(DataInputStream in, Client c){
    client = c;
    this.in = in;
    thread = new Thread(this);
    thread.start();
}

@Override
public void run() {
    boolean enabled = true;
    while(enabled){

    }

}

Server code ment to send/recieve and reroute both UTF and Object packets 发送/接收和重新路由UTF和对象数据包的服务器代码

public DataOutputStream out;
public DataInputStream in;
public User[] user;
public int slots;
public int id;
InetAddress address;
Server server;
public String username = "";
public boolean enabled;
public boolean ticking;
public boolean allDataSent;
int currentCanvas = 0;
private boolean playerConnected;

public boolean imageByteReady=true;
private boolean sendImage;

public User(DataOutputStream out, DataInputStream in, User[] user, int slots, int i, InetAddress inetAddress, Server server, String username){
    this.out = out;
    this.in = in;
    this.user = user;
    this.slots = slots;
    this.id = i;
    address = inetAddress;
    this.server = server;
    this.username = username;
    ticking = true;
}

@Override
public void run() {
    enabled = true;
    while(enabled){
        try {
            String data = in.readUTF();
            if(valid(data)){
            for(int i = 0; i < slots; i++){
                if(user[i]!=null){

                    if(data.contains("timedout/")){
                        data = data.split("timedout/")[1];
                        if(Integer.valueOf(data) == 1){
                            server.printOut(server.disconnectMessage(id, "Client disconnected because server didnt tick."));
                            user[id] = null;
                            enabled = false;
                        } else {
                            server.printErr("Got an invalid timeout packet. Packet: timedout/"+data);
                        }
                    }

                    if(data.contains("clienttick/")){
                        data = data.split("clienttick/")[1];
                        out.writeUTF("servertick/"+data);
                        server.packetManager.resetClientWithID(Integer.valueOf(data));
                    }

                    if(data.contains("drawcircle/") || data.contains("erasecircle/") || data.contains("chatmessage/"))
                    user[i].out.writeUTF(data);

                }
            }
            if(data.contains("switchcanvas/")){
                data = data.split("switchcanvas/")[1];
                    if(server.canvasaccessmanager.playerCanBeOnCanvas(id, Integer.valueOf(data)) && Integer.valueOf(data) != currentCanvas){
                        out.writeUTF("changeCanvas/"+data);
                        currentCanvas = Integer.valueOf(data);
                        server.printOut(user[id].username+" switched to canvas "+(Integer.valueOf(data)+1));
                    } else if(!server.canvasaccessmanager.playerCanBeOnCanvas(id, Integer.valueOf(data))){
                        out.writeUTF("changeCanvasFailed/"+data);
                        server.printOut(user[id].username+" was denied access to canvas "+(Integer.valueOf(data)+1));
                    }
            }

            if(data.contains("sendImage/")){
                data = data.split("sendImage/")[1];
                sendImage = Boolean.valueOf(data);
            }

            if (data.contains("drawcircle/")) {
                data = data.split("drawcircle/")[1];
                String[] tokens = data.split("/");
                int x = 0, y = 0, width = 0, height = 0, r = 0, g = 0, b = 0, id = 0, alpha = 0;
                for (int i = 0; i < tokens.length; i++) {
                    if (i == 0)
                        x = Integer.valueOf(tokens[i]);
                    if (i == 1)
                        y = Integer.valueOf(tokens[i]);
                    if (i == 2)
                        width = Integer.valueOf(tokens[i]);
                    if (i == 3)
                        height = Integer.valueOf(tokens[i]);
                    if (i == 4)
                        r = Integer.valueOf(tokens[i]);
                    if (i == 5)
                        g = Integer.valueOf(tokens[i]);
                    if (i == 6)
                        b = Integer.valueOf(tokens[i]);
                    if (i == 7)
                        id = Integer.valueOf(tokens[i]);
                    if (i == 8)
                        alpha = Integer.valueOf(tokens[i]);
                }
                server.canvasManager.drawCircle(x, y, width, height, r, g, b, alpha, id);
            }

            if (data.contains("erasecircle/")) {
                data = data.split("erasecircle/")[1];
                String[] tokens = data.split("/");
                int x = 0, y = 0, width = 0, height = 0, id = 0;
                for (int i = 0; i < tokens.length; i++) {
                    if (i == 0)
                        x = Integer.valueOf(tokens[i]);
                    if (i == 1)
                        y = Integer.valueOf(tokens[i]);
                    if (i == 2)
                        width = Integer.valueOf(tokens[i]);
                    if (i == 3)
                        height = Integer.valueOf(tokens[i]);
                    if (i == 7)
                        id = Integer.valueOf(tokens[i]);
                }
               server.canvasManager.eraseCircle(x, y, width, height, id);
            }

            if(data.contains("chatmessage/")){

                data = data.split("chatmessage/")[1];
                String[] tokens = data.split("/");
                String user = "";
                String message = "";
                for (int x = 0; x < tokens.length; x++) {
                    if (x == 0)
                        user = tokens[0];
                    if (x == 1)
                        message = tokens[1];

                }
                server.printOut(user + " said '" + message+"'");
            }
            } else {
                server.printErr("Caught an overlapped packet from client "+id);
                server.packetManager.resetClientWithID(id);
            }
        } catch (IOException e) {
            if(enabled){
            server.printOut(server.disconnectMessage(id, "Client socket closed. Manual disconnect?"));
            user[id] = null;
            enabled = false;
            }
        }

    }
    saveUserData();
    if(playerConnected)
        sendLeaveMessage();
}

private boolean valid(String data) {
    String[] tokens = data.split("/");
    if(tokens[1].toLowerCase().contains(inputFix(tokens[0]))){

        return false;
    }
    return true;
}

private String inputFix(String data) {
    return data.replaceAll("[^a-zA-Z]", "").toLowerCase().trim();
}

private void saveUserData() {
    server.playermanager.setUserProperty(username, "currentCanvas", String.valueOf(currentCanvas));
}

public void sendID() {
    try {
        out.writeUTF("id/"+id);
        playerConnected = true;
    } catch (IOException e) {
    e.printStackTrace();
    }
}

public void sendCanvases() {
    try{
    sendCanvas(0);
    server.printOut("Sent canvas 0");
    Thread.sleep(1);
    } catch(Exception e){
        server.printErr("Failed to send canvas 0");
        sendCanvases();
    }
}

public void sendCanvas(int id) throws Exception{
}


public void sendLeaveMessage(){
    for(int i = 0; i < slots; i++){
        if(i != id){
            if(user[i] != null){
                try {
                    user[i].out.writeUTF("playerleave/"+username);
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }
}

public void sendJoinMessage() {
    for(int i = 0; i < slots; i++){
        if(i != id){
            if(user[i] != null){
            try {
                user[i].out.writeUTF("playerjoin/"+username);
            } catch (IOException e) {
                e.printStackTrace();
            }
            }
        }
    }
}

public void sendData() {
    if(server.playermanager.userExists(username)){
        int x = Integer.parseInt(server.playermanager.loadUserProperty(username, "currentCanvas"));
        currentCanvas = x;
        try {
            out.writeUTF("overrideChangeCanvas/"+x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return;
    }
    //If user is new;
    int x = server.canvasaccessmanager.nextOpenCanvas(username);
    try {
        currentCanvas = x;
        out.writeUTF("overrideChangeCanvas/"+x);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void setUpUserData() {
    if(!server.playermanager.userExists(username)){
        server.playermanager.createUser(username);
    }
}

Client code: 客户代码:

 public Dimension dimension;
 static final long serialVersionUID = 1L;
public Thread thread;
public int currentfps;
public long start;
public int fps;

static Socket socket;
public static DataInputStream in ;
public Listener listener = null;
public boolean isRunning = true;
public boolean justClicked;
public static int canvasMax = 10;
public Canvas[] canvas = new Canvas[canvasMax];
public int currentCanvas;
public Graphics canvasGraphics;
public Player player;
public DataOutputStream out;
public boolean connectedToServer = false;
public boolean click;
public int id;
public Image screen;
public static Toolkit toolkit = Toolkit.getDefaultToolkit();
public static Image cursor = toolkit.getImage("res/icons/cursor.png");
public static Image tabCanvas = toolkit.getImage("res/image/tabs/tabCanvas.png");
public static Image tabColor = toolkit.getImage("res/image/tabs/tabColor.png");
public Image tabGuide = toolkit.getImage("res/image/tabs/tabGuide.png");;
public static Image[] guideImages = new Image[canvasMax];
public int tabOffset = 0, tabWidth = 200, currentTabWidth = 0, tabHeight = 0;
public boolean ChatOpen;
public CanvasGUI canvasgui;
public int currentColor;
public int colorMax = 10;
public boolean serverHasResponded = false;
public int wait;
public Data data;


public Chat chat;

public int defaultPort = 58828;
public int port = 0;
public String ip = "";

public ColorGUI colorgui;
public GuideGUI guidegui;
public int currentGuide;
public int waitMax = 1000000;
public HeartbeatManager heartbeatManager;

public ArrayList<Popup> popups;
public Integer lastCanvasClick;
private boolean debug;

public ServerLogin serverLogin;
public boolean serverLoginOpen;
public Component comp;
int index;
public boolean started;
private boolean disconnecting;
public boolean clientHasRecieved;

public Client(Component component) {
    this.comp = component;
}
public void connectClient(String ip, int port) {

    try {
        this.ip = ip;
        this.port = port;
        socket = new Socket(ip, port); 
        in = new DataInputStream(socket.getInputStream());
        out = new DataOutputStream(socket.getOutputStream());
        connectedToServer = true;
        out.writeUTF("authenticate/" + comp.authenticated);
        out.writeUTF("username/" + comp.username);
        out.writeUTF("version/" + comp.version);
        data = new Data( in , this);
        Thread thread = new Thread(data);
        data.setThread(thread);
        thread.start();
        DataObjects dataObjects = new DataObjects(in, this);
    } catch (Exception e) {
        comp.printErr("Failed to connect to server, " + e.toString());
        disconnectClient("Failed to connect");
    }
}
public void disconnectClient(String var1) {
    if(!disconnecting){
    disconnecting = true;
    try {
        in = null;
        out = null;
        if (data != null){
            data.enabled = false;
            data = null;
        };
        if(connectedToServer)
        socket.close();
        socket = null;
        connectedToServer = false;
        serverHasResponded = false;
        wait = 0;
        String str = "Disconnected from server "+ip+":"+port+", "+var1;
        comp.printOut(str);
        ip = "";
        port = 0;
        comp.stopGame();
        comp.startWarningMenu(str);
    } catch (Exception e) {
        e.printStackTrace();
    }
    }
}


void initializing(int i) {
    index = i;
    comp.printOut("Index: "+i+".");
    tabHeight = comp.height;
    isRunning = true;
    comp.printOut("Creating Canvases.");
    for (int x = 0; x < canvasMax; x++) {
        canvas[x] = new Canvas(this);
        canvas[x].clear(0, 0, comp.width, comp.height);
        comp.printOut("Creating Canvas"+(x+1)+".");
    }
    comp.printOut("Canvases Created.");
    comp.printOut("Loading Guides.");
    for (int x = 0; x < guideImages.length; x++) {
        guideImages[x] = toolkit.getImage("res/image/guides/guides_" + x + ".png");
        if (!new File("res/image/guides/guides_" + x + ".png").exists()) {
            guideImages[x] = toolkit.getImage("res/image/guides/guides_0.png");
            comp.printErr("Couldnt Locate Guide"+(x+1)+".");
        } else {
            comp.printOut("Loaded Guide"+(x+1)+".");
        }
    }
    colorgui = new ColorGUI(this);
    comp.printOut("Loaded ColorGUI.");
    guidegui = new GuideGUI(this);
    comp.printOut("Loaded GuideGUI.");
    chat = new Chat(this);
    comp.printOut("Loaded Chatting Class.");
    popups = new ArrayList<Popup>();
            comp.printOut("Loaded ArrayList<Popup>.");
    currentCanvas = 0;
    heartbeatManager = new HeartbeatManager(this);
    comp.printOut("Loaded Heartbeat Manager.");
    canvasgui = new CanvasGUI(this);
    comp.printOut("Loaded CanvasGUI.");
    screen = comp.createImage(comp.pixel.width, comp.pixel.height);
    comp.printOut("Loaded Screen Component.");
    player = new Player(this);
    comp.printOut("Loaded Player Class.");
    serverLogin = new ServerLogin(this);
    comp.printOut("Loaded Server Login GUI.");
    started = true;
    comp.printOut("Starting Threads. Game Loading done!");
    thread = new Thread(this);
    thread.setPriority(6);
    thread.start();
    }

Looks like a case for buffering to get better throughput. 看起来是为了获得更好的吞吐量而进行缓冲的情况。 I see you instantiating DataInputStream/DataOutputStream, but those aren't buffered so I think you could get a big boost by adding BufferedInput/OutputStream to each side. 我看到您实例化了DataInputStream / DataOutputStream,但是没有对它们进行缓冲,因此我认为可以通过在每侧添加BufferedInput / OutputStream来获得很大的提升。 I don't see your code where you copy the image to the stream. 我看不到您将代码复制到流中的代码。 So the following should help: 因此,以下内容应有所帮助:

in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));

Just remember to flush(). 只记得刷新()。 The other option you can do is compress your data before sending it over the stream. 您可以做的另一种选择是在通过流发送数据之前先压缩数据。 If you are sending a 1920x1080 image uncompressed would be around 8MB (=1920px * 1080px * 4 bytes / pixel) so 5-10s is not a surprising. 如果要发送未压缩的1920x1080图像,则约为8MB(= 1920px * 1080px * 4字节/像素),因此5-10s并不奇怪。 Adding a GZipInputStream on top of that is pretty simple, and would compress all data sent. 在此之上添加GZipInputStream非常简单,它将压缩所有发送的数据。 Image specific compression would probably achieve a higher compression, but more involved. 特定于图像的压缩可能会实现更高的压缩,但涉及更多。

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

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