我正在转移不同类型文件的字节数组(.png,.txt等)。我的套接字开始发送数据,客户端开始接收它。出于某种原因,.pngs看起来与在服务器端看起来不一样。 (有时它说图像不可读,有时只显示图像的某些部分等等)?我想知道我怎么能这样做,以便发送的数据实际上与发送的数据相同?我有什么错误吗? (注意!如果.png文件有alpha通道,图像似乎总是完全不可读。)
数据传输的客户端:
try
{
sInput = new ObjectInputStream(socket.getInputStream());
Input = socket.getInputStream();
}
catch (IOException eIO) {
System.out.println("Exception creating new Input/output Streams: " + eIO);
return false;
}
.
.
.
LoadCache[] filedata = (LoadCache[]) sInput.readObject(); //This contains the path and size of file
while(number < filedata.length){
byte[] mybytearray = new byte[(int) LoadCache.getSize(filedata[number])];
String result = Reader.UpdateCache(LoadCache.getPath(filedata[number]));
number++;
if(result != "skip" && result != "Stop"){
BufferedOutputStream Bos = new BufferedOutputStream(new FileOutputStream(result));
int BytesRead = Input.read(mybytearray, 0, mybytearray.length);
Bos.write(mybytearray, 0, BytesRead);
Bos.close();
}
}
数据传输的服务器端:
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
OutputStream Output;
BufferedInputStream buffIn;
.
.
.
try{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
Output = socket.getOutputStream();
} catch (Exception e){
System.out.println("Couldn't create Input/Output streams");
}
.
.
.
File[] Data = Reader.getFiles(Action.getString(Incomingdata.getAction(datain)));
LoadCache LoadedCache[] = new LoadCache[Data.length];
for(int i = 0; i<Data.length; i++){
Path filePath = Paths.get(Data[i].getPath());
Path relativePath = base.relativize(filePath); //= filePath - base (so to say)
LoadedCache[i] = new LoadCache(relativePath.toString(), Data[i].length());
}
System.out.println(LoadedCache.length);
try {
sOutput.writeObject(LoadedCache);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(File file : Data){
try {
if(file.isFile()){
byte[] bytearray = new byte[(int) file.length()];
buffIn = new BufferedInputStream(new FileInputStream(file));
buffIn.read(bytearray, 0, bytearray.length);
Output.write(bytearray, 0, bytearray.length);
Output.flush();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
buffIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
另外!现在(如果我之前得到的话,我不太确定)客户端给我java.util.zip.ZipException: incorrect header check
-Exception(并且没有任何文件是压缩的)
Something Runnable:
Public class Client {
private ObjectInputStream sInput; // to read from the socket
private static ObjectOutputStream sOutput; // to write on the socket
private static Socket socket;
public static Client client;
public static Player player;
public static boolean loadingFiles;
String server;
int port;
boolean connected;
Client(String server, int port) {
this.server = server;
this.port = port;
this.connected = true;
}
public static boolean isConnected(Client client){
return client.connected;
}
private void disconnect() {
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {} // not much else I can do
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {} // not much else I can do
try{
if(socket != null) socket.close();
}
catch(Exception e) {} // not much else I can do
}
public boolean start() {
// try to connect to the server
try {
socket = new Socket(server, port);
}
// if it failed we catch the exception
catch(Exception ec) {
System.out.println("Error connecting to server: " + ec);
return false;
}
System.out.println("Connection accepted " + socket.getInetAddress() + ":" + socket.getPort());
/* Creating Data Streams */
try
{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
}
catch (IOException eIO) {
System.out.println("Exception creating streams: " + eIO);
return false;
}
// creates the Thread to listen from the server
new ListenFromServer().start();
String Cache;
if(Reader.ReadCache(Frame.drive +"//FM_Cache/version") == "WeHadToMakeNewFile"){ //If we don't have that file. We create it, but now it's empty.
Cache = "New";
}
else{ //If we do have cache and it has "version" we send our version to server.
Cache = Reader.ReadCache(Frame.drive +"FM_Cache/version");
}
send(new Incomingdata("", "", new Action(0, Cache, 0, 0)));
// success we inform the caller that it worked
return true;
}
public static void Connect() {
// default values
int portNumber = 16304;
String serverAddress = "0.0.0.0"; //I'm using my own ip here..
// create the Client object
client = new Client(serverAddress, portNumber);
// test if we can start the connection to the Server
if(client.start()){
client.connected = true;
}
}
public static void Disconnect(Client client) {
client.connected = false;
client.disconnect();
}
class ListenFromServer extends Thread {
public void run() {
loadingFiles = true;
while(true) {
try {
int number = 0;
LoadCache[] filedata = (LoadCache[]) sInput.readObject();
while(number < filedata.length){
byte[] mybytearray = new byte[(int) LoadCache.getSize(filedata[number])];
String result = Reader.UpdateCache(LoadCache.getPath(filedata[number]));
number++;
if(result != "skip" && result != "Stop"){
BufferedOutputStream Bos = new BufferedOutputStream(new FileOutputStream(result));
int BytesRead = sInput.read(mybytearray, 0, mybytearray.length);
Bos.write(mybytearray, 0, BytesRead);
Bos.close();
}
}
System.out.println("Cache has been patched succesfully!");
Client.loadingFiles = false;
}catch(EOFException e){
System.out.println("Problem reading the data streams! " +e);
break;
}
catch(IOException e) {
System.out.println(e);
break;
}
catch(ClassNotFoundException e2) {
}
}
}
}
public static void send(Incomingdata incomingdata) {
try {
sOutput.writeObject(incomingdata);
}
catch(IOException e) {
System.out.println("Exception writing to server: " + e);
}
}
}
Incomingdata:
package com.connection;
import com.connection.Action;
public class Incomingdata implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -1309997274550304156L;
private String Username, Password;
private Action action;
public Incomingdata(String Username, String Password, Action action){
this.Username = Username;
this.action = action;
this.Password = Password;
}
public static String getUsername(Incomingdata Incomingdata){
return Incomingdata.Username;
}
public static String getPassword(Incomingdata Incomingdata){
return Incomingdata.Password;
}
public static Action getAction(Incomingdata Incomingdata){
return Incomingdata.action;
}
}
LoadingCache:
package com.connection;
import java.io.Serializable;
public class LoadCache implements Serializable{
/**
*
*/
private static final long serialVersionUID = 7267682639705707967L;
String path;
long size;
public LoadCache(String path, long size){
this.path = path;
this.size = size;
}
public static long getSize(LoadCache cache) {
return cache.size;
}
public static String getPath(LoadCache filedata) {
return filedata.path;
}
}
Action.java:
package com.connection;
import com.connection.Action;
public class Action implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 4389420849399916526L;
int type, x, y;
String string;
public Action(int type, String string, int x, int y){
this.type = type;
this.string = string;
this.x = x;
this.y = y;
}
public static int getType(Action action) {
return action.type;
}
public static String getString(Action action) {
return action.string;
}
public static int getX(Action action) {
return action.x;
}
public static int getY(Action action) {
return action.y;
}
}
和客户读者。这应该是运行客户端所需的最后一个类。
package com.game.loader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import com.connection.Client;
import com.game.Frame;
import com.game.menu.GameMenu;
public class Reader {
public static String ReadCache(String string) {
int CurrentLine = 0;
String returnement = "";
try {
BufferedReader Reader = new BufferedReader(new FileReader(new File(string)));
for(String line = Reader.readLine(); line != null; line = Reader.readLine()){
if(CurrentLine == 0){
returnement = line;
}
CurrentLine++;
}
} catch (FileNotFoundException e) {
new File(Frame.drive +"//FM_Cache").mkdirs();
return "WeHadToMakeNewFile";
} catch (IOException e) {
e.printStackTrace();
}
return returnement;
}
public static String UpdateCache(String path) {
String[] pieces = path.split("/");
String returnement = "skip";
System.out.println(Frame.drive + "//FM_Cache/" + path);
if(new File(Frame.drive +"//FM_Cache/" +path).exists()){
returnement = (Frame.drive +"//FM_Cache/" +path);
}
else{ //If file doesen't exit we make one and parent folders.
File file = new File(Frame.drive +"//FM_Cache/" +path);
file.getParentFile().mkdirs();
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
returnement = (Frame.drive +"//FM_Cache/" +path);
}
return returnement;
}
}
可运行的服务器:
package com.server;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.ServerSocket;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import org.apache.commons.io.IOUtils;
import com.connection.Action;
import com.connection.Incomingdata;
import com.connection.LoadCache;
import com.game.loader.Reader;
import com.game.player.Player;
public class Server {
//Every connection got their own unique id
private static int uniqueId;
//List all the clients
private static ArrayList<ClientThread> al;
private static boolean running = false;
@SuppressWarnings("unused")
private SimpleDateFormat sdf;
final Path base = Paths.get("Data", "Cache");
public Server(int port) {
sdf = new SimpleDateFormat("HH:mm:ss");
al = new ArrayList<ClientThread>();
}
public void start() {
running = true;
try {
//Server socket
ServerSocket serverSocket = new ServerSocket(Screen.portnumber);
System.out.println("Server is running and waiting for Clients to connect.");
while(running){
Socket socket = serverSocket.accept();
if(!running){ //this will make server running stop.
System.out.println("Closing the server..");
break;
}
ClientThread t = new ClientThread(socket);
al.add(t); //saving new client to our arraylist.
t.run();
}
try{
serverSocket.close();
for(int i = 0; i< al.size(); i++){//We forget about all the clients.
//Maybe also save all the data here?
ClientThread tc = al.get(i);
try{
tc.sInput.close();
tc.sOutput.close();
tc.socket.close();
}
catch(IOException ioE){}
}
} catch(Exception e){e.printStackTrace();}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void close() {
running = false;
try {
new Socket("localhost", Screen.portnumber);
} catch (Exception e) { System.out.println("Can't disconnect.."); }
}
synchronized void remove(int id) {
// scan the array list until we find the Id
for(int i = 0; i < al.size(); ++i) {
ClientThread ct = al.get(i);
// found it
if(ct.id == id) {
al.remove(i);
return;
}
}
}
public static boolean isRunning(){
return running;
}
class ClientThread extends Thread {
//The socket where to listen/talk
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
BufferedInputStream buffIn;
//my unique id (easier for deconnection)
int id;
//Objects that we will be receiving
Incomingdata datain;
//the date we connect
String date;
Player player;
boolean Connected = false;
//Constructor
ClientThread(Socket socket){
id = uniqueId++;
this.socket = socket;
try{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
} catch (Exception e){
System.out.println("Couldn't create Input/Output streams");
}
date = new Date().toString();
}
// what will run forever
public void run() {
// to loop until LOGOUT
Connected = true;
while(Connected) {
try {
datain = (Incomingdata) sInput.readObject();
}
catch (IOException e) {
System.out.println("Exception reading Streams: " + e);
break;
}
catch(ClassNotFoundException e2) {
break;
}
if(!Incomingdata.getUsername(datain).isEmpty()){
switch(Action.getType(Incomingdata.getAction(datain))) { //CHANGE!!
case 0://Log in/off
System.out.println(Incomingdata.getUsername(datain) +", " +Incomingdata.getPassword(datain) + " trying to connect.");
if(Player.getPassword(Reader.ReadPlayerData("Data/Players/" +Incomingdata.getUsername(datain) +".txt")) == Incomingdata.getPassword(datain)){
player = Reader.ReadPlayerData("Data/Players/" +Incomingdata.getUsername(datain) +".txt");
System.out.println(Player.getUsername(player) +"Just connected!");
Player.isOnline(player);
}
break;
case 1://Talk
System.out.println(Incomingdata.getUsername(datain) + ": " +Action.getString(Incomingdata.getAction(datain)));
break;
case 2://Move
break;
}
}
else if(Action.getString(Incomingdata.getAction(datain)) != null){
File[] Data = Reader.getFiles(Action.getString(Incomingdata.getAction(datain)));
LoadCache LoadedCache[] = new LoadCache[Data.length];
for(int i = 0; i<Data.length; i++){
Path filePath = Paths.get(Data[i].getPath());
Path relativePath = base.relativize(filePath); //= filePath - base (so to say)
LoadedCache[i] = new LoadCache(relativePath.toString(), Data[i].length());
}
System.out.println(LoadedCache.length);
try {
sOutput.writeObject(LoadedCache);
sOutput.flush();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
for(File file : Data){
try {
if(file.isFile()){
byte[] bytearray = new byte[(int) file.length()];
buffIn = new BufferedInputStream(new FileInputStream(file));
buffIn.read(bytearray, 0, bytearray.length);
sOutput.write(bytearray, 0, bytearray.length);
sOutput.flush();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
buffIn.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Cache updated!");
}
}
// remove myself from the arrayList containing the list of the
System.out.println(Player.getUsername(player) +", " +Player.getPassword(player) +" disconnected.");
remove(id);
close();
}
// try to close everything
private void close() {
// try to close the connection
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {};
try {
if(socket != null) socket.close();
}
catch (Exception e) {}
}
}
}
服务器的Reader.java:
package com.game.loader;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import org.apache.commons.io.filefilter.FileFileFilter;
import com.game.player.CharacterClass;
import com.game.player.Equipment;
import com.game.player.Friends;
import com.game.player.Inventory;
import com.game.player.Orbs;
import com.game.player.Player;
import com.game.player.Quest;
import com.game.world.Tile;
public class Reader {
public static Player temporary;
static int stage = 0;
private static int count = 0;
private static int totalfolders = 0;
private static File[] files = new File[NumberOfFiles("Data/Cache/")];
public static Player ReadPlayerData(String string) {
Player player = null;
int CurrentLine = 0;
String[] All = new String[100]; //This may need to be extended.
try {
BufferedReader Reader = new BufferedReader(new FileReader(new File(string)));
for(String line = Reader.readLine(); line != null; line = Reader.readLine()){
All[CurrentLine] = line;
CurrentLine++;
}
} catch (FileNotFoundException e) {
System.out.println("Someone is trying to log in using wrong username.");
} catch (IOException e) {
e.printStackTrace();
}
player = new Player(string, All[0], new Tile(Integer.parseInt(All[1].split(", ")[0]), Integer.parseInt(All[1].split(", ")[1]), Integer.parseInt(All[1].split(", ")[2])),
Integer.parseInt(All[2]), Integer.parseInt(All[3]), Integer.parseInt(All[4]), new CharacterClass(All[5]), new Orbs(All[6].split(", ")), null, new Inventory(All[8].split(", ")),
null, new Equipment(All[10].split(", ")), new Friends(All[11].split(", ")), /* All[12] = guild,*/ Integer.parseInt(All[13]), true, false, null, null, Integer.parseInt(All[18]), /*All[19] = StartDate,*/ All[20]);
temporary = player;
return player;
}
public static boolean CacheReader(String string) {
File[] all = new File(string).listFiles(); //We list all the files from path
int folders = 0;
for(int i = 0; i < all.length; i++){
if(!all[i].isDirectory()) { //folders are not added to this list. :)
System.out.println("((i = " +i +") - (folders = " +folders +")) + (stage = " +stage +") = " +(i-folders+stage));
files[i-folders+stage] = all[i];
}
else{
folders++;
totalfolders++;
}
}
stage += all.length-folders; //We add number of files from every directory to stage.
for(int i = 0; i < all.length; i++){ //Then we seek for all the sub-directories
if(all[i].isDirectory()){
CacheReader(all[i].getPath()); //and add all the files from sub-directories to out file list
}
}
return true;
}
public static File[] getFiles(String string) {
if(string == "New"){
}
return files;
}
public static int NumberOfFiles(String string) {
File[] filenames;
filenames = new File(string).listFiles();
count += filenames.length; //We add all the files from the File(string) Note!: Also folders
for(int i = 0; i < filenames.length; i++){
if(filenames[i].isDirectory()){
NumberOfFiles(filenames[i].getPath());
count--;
}
}
return count;
}
}
嗯..我认为你可以删除与播放器相关的所有内容,因为它不是缓存更新系统的一部分..还有一些未使用的导入,我没有删除所有这些。大多数TextArea.Addline(); s我改为System.out.println();如果你找到一个,你也可以用System.out.println()替换它;或者如果您不需要它,您可以将其删除。什么......我只想找到答案..
答案 0 :(得分:0)
尝试将字节数组作为对象写入ObjectOutputStream:
final byte[] bytearray = new byte[(int) file.length()];
buffIn = new BufferedInputStream(new FileInputStream(file));
buffIn.read(bytearray, 0, bytearray.length);
sOutput.writeObject(bytearray);
并将其作为对象阅读:
final BufferedOutputStream Bos =
new BufferedOutputStream(new FileOutputStream(result));
byte[] mybytearray = (byte[])sInput.readObject();
Bos.write(mybytearray, 0, BytesRead);
我希望它有所帮助。
答案 1 :(得分:-1)
不要使用多个流从同一个套接字读取,也不要写入它。使用对象流来处理所有事情。
您的复制循环不正确,因为它们不是循环。您不能假设read()
填充缓冲区。 Java中的规范流复制循环是这样的:
int count;
byte[] buffer = new byte[8192]; // or more, code works with any size >= 1
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}