我在让服务器通过套接字发送图像时遇到问题。我需要在至少5-10秒的时间内将10张1920x1080图像发送给客户端。我似乎在任何地方都遇到错误,或者我的客户端/服务器故障发生故障并且无法以某些方式发送。任何人都可以指出我正确的方向并告诉我一种方法来实现这一点而不会弄乱其他过程吗?
非对象事物的客户端代码,用于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 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){
}
}
发送/接收和重新路由UTF和Object数据包的服务器代码
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);
}
}
客户代码:
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();
}
答案 0 :(得分:0)
看起来像缓冲以获得更好的吞吐量。我看到你实例化DataInputStream / DataOutputStream,但是那些没有缓冲,所以我认为你可以通过向每一侧添加BufferedInput / OutputStream来获得巨大的提升。我没有看到您将代码复制到流中的代码。所以以下内容应该有所帮助:
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
记住要冲洗()。您可以执行的另一个选项是在通过流发送数据之前压缩数据。如果您要发送1920x1080图像,未压缩的图像大约为8MB(= 1920px * 1080px * 4字节/像素),因此5-10s并不令人惊讶。在其上添加GZipInputStream非常简单,并且会压缩发送的所有数据。图像特定的压缩可能会实现更高的压缩,但更多的参与。