Java Android:从服务器上的套接字接收空对象
我有一个服务器/客户端应用程序,用于发送/接收有关应用程序成员用户的更新。不幸的是,当Android设备上的客户端发送任何getUpdate/sendUpdate对象时,服务器会将其接收为null 我还有一个PC版的安卓客户端,运行非常好。它有相同的方法和一切 以下是Android设备上的客户端:Java Android:从服务器上的套接字接收空对象,java,android,sockets,Java,Android,Sockets,我有一个服务器/客户端应用程序,用于发送/接收有关应用程序成员用户的更新。不幸的是,当Android设备上的客户端发送任何getUpdate/sendUpdate对象时,服务器会将其接收为null 我还有一个PC版的安卓客户端,运行非常好。它有相同的方法和一切 以下是Android设备上的客户端: public class AndroidApplication extends Application{ public static Log log; private final static St
public class AndroidApplication extends Application{
public static Log log;
private final static String TAG = "AndroidApplication";
public static final String SERVER = "192.168.1.136";
public static boolean chatCreated = false;
public static String chatText;
public static String username, level = MemberMessage.LEVEL4;
public static Context context;
public static int points = 0;
public static UpdateMember k;
@Override
public void onCreate(){
super.onCreate();
context = getApplicationContext();
}
public static void updateMember(){
k = new UpdateMember(UpdateMember.SEND);
k.start();
}
public static void getUpdateMember(){
k = new UpdateMember(UpdateMember.GET);
k.start();
}
public static void stopUpdateMember(){
AndroidApplication.k = null;
}
static class UpdateMember extends Thread{
static final int GET=0,SEND=1;
boolean didConnectWork;
boolean didUpdateWork;
boolean didDisconnectWork;
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
boolean GetSend;
public UpdateMember(int get_send){
switch(get_send){
case UpdateMember.GET:
GetSend = true;
break;
case UpdateMember.SEND:
GetSend = false;
break;
}
}
public void run(){
if(GetSend){
didConnectWork = connect();
didUpdateWork = getUpdate();
getInfoFromServer();
didDisconnectWork = disconnect();
}else{
didConnectWork = connect();
didUpdateWork = sendUpdate();
try{
getInfoFromServer();
}catch(Exception e){
Log.i(TAG, "Something Bad");
}
didDisconnectWork = disconnect();
}
AndroidApplication.stopUpdateMember();
}
private boolean connect() {
try{
socket = new Socket(SERVER, 1520);
}catch(Exception e){
Log.i(TAG, "Couldn't connect to Member Server");
Log.i(TAG, e.getMessage());
return false;
}
Log.i(TAG, "Connection Accepted at Membe Server!");
/*
* Create both data streams
*/
try{
sInput = new ObjectInputStream(socket.getInputStream());
sOutput = new ObjectOutputStream(socket.getOutputStream());
}catch(IOException e){
Log.i(TAG, "Couldn't connect to Member Server");
return false;
}
try{
sOutput.writeObject(username);
}catch(IOException e){
Log.i(TAG, "Couldn't send username.");
return false;
}
//everything worked
Log.i(TAG, "Connected to Member Server.");
return true;
}
private boolean sendUpdate() {
MemberMessage mh = new MemberMessage(MemberMessage.UPDATE, AndroidApplication.username,
AndroidApplication.points, AndroidApplication.level);
try{
sOutput.writeObject(mh);
}catch(IOException e){
Log.i(TAG, "Couldn't update info");
return false;
}
//everything worked!
Log.i(TAG, Integer.toString(mh.getType()));
Log.i(TAG, "Update sent!");
return true;
}
private boolean getUpdate(){
try{
sOutput.writeObject(new MemberMessage(MemberMessage.UPDATE_REQUEST,
AndroidApplication.username, -1, null));
}catch(IOException e){
Log.i(TAG, "Couldn't send GET message info");
return false;
}
//itworked
Log.i(TAG, "GET Update sent!");
return true;
}
private void getInfoFromServer(){
MemberMessage MM;
/*
* Will listen for both an update message and a Diconnect messafge form the
* server.
*/
boolean keep = true;
while(keep){
//************************************
try{
MM = (MemberMessage) sInput.readObject();
}catch(IOException e){
Log.i(TAG, "Couldn't read message from server.");
break;
} catch (ClassNotFoundException e) {
Log.i(TAG, "Couldn't update info");
break;
}
//the message to stop listening for updates
switch(MM.getType()){
case MemberMessage.DISCONECT:
Log.i(TAG, "Received dsconnect message.");
keep = false;
break;
case MemberMessage.UPDATE:
/*
* Update our info in turn
*/
AndroidApplication.points = MM.getNumPoints();
AndroidApplication.level = MM.getLevel();
Log.i(TAG, "Updatted member with Points = " + AndroidApplication.points
+ " and Level = " + AndroidApplication.level);
try{
//tell the sever we recieved the info
sOutput.writeObject(new MemberMessage(MemberMessage.RECIEVED, null, -1, null));
}catch(IOException e){
Log.i(TAG, "Couldn't send received message");
keep = false;
}
break;
}
//*****************************************
}
}
private boolean disconnect() {
try{
sOutput.writeObject(new MemberMessage(MemberMessage.DISCONECT, null, -1, null));
}catch(IOException e){
Log.i(TAG, "Couldn't disconnet");
}
// try to close the connection
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {
Log.i(TAG, "Couldn't close output");
return false;
}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {
Log.i(TAG, "Couldn't close input");
return false;
}
try {
if(socket != null) socket.close();
}
catch (Exception e) {
Log.i(TAG, "Couldn't close socket");
return false;
}
return true;
}
}
}
对于PC版本:
public class UpdateTest {
public static final String SERVER = "192.168.1.136";
public static boolean chatCreated = false;
public static String chatText;
public static String username = "TESTER", level = MemberMessage.LEVEL1;
public static int points = 90;
public static UpdateMember k;
public static void updateMember(){
k = new UpdateMember(UpdateMember.SEND);
k.start();
}
public static void getUpdateMember(){
k = new UpdateMember(UpdateMember.GET);
k.start();
}
public static void stopUpdateMember(){
UpdateTest.k = null;
}
static class UpdateMember extends Thread{
static final int GET=0,SEND=1;
boolean didConnectWork;
boolean didUpdateWork;
boolean didDisconnectWork;
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
boolean GetSend;
public UpdateMember(int get_send){
switch(get_send){
case UpdateMember.GET:
GetSend = true;
break;
case UpdateMember.SEND:
GetSend = false;
break;
}
}
public void run(){
if(GetSend){
didConnectWork = connect();
didUpdateWork = getUpdate();
getInfoFromServer();
didDisconnectWork = disconnect();
}else{
didConnectWork = connect();
didUpdateWork = sendUpdate();
getInfoFromServer();
didDisconnectWork = disconnect();
}
UpdateTest.stopUpdateMember();
}
private boolean connect() {
try{
socket = new Socket(SERVER, 1520);
}catch(Exception e){
return false;
}
/*
* Create both data streams
*/
try{
sInput = new ObjectInputStream(socket.getInputStream());
sOutput = new ObjectOutputStream(socket.getOutputStream());
}catch(IOException e){
return false;
}
try{
sOutput.writeObject(username);
}catch(IOException e){
return false;
}
//everything worked
return true;
}
private boolean sendUpdate() {
try{
sOutput.writeObject(new MemberMessage(MemberMessage.UPDATE, UpdateTest.username,
UpdateTest.points, UpdateTest.level));
}catch(IOException e){
return false;
}
//everything worked!
return true;
}
private boolean getUpdate(){
try{
sOutput.writeObject(new MemberMessage(MemberMessage.UPDATE_REQUEST,
UpdateTest.username, -1, null));
}catch(IOException e){
return false;
}
//itworked
return true;
}
private void getInfoFromServer(){
MemberMessage MM;
/*
* Will listen for both an update message and a Diconnect messafge form the
* server.
*/
boolean keep = true;
while(keep){
//************************************
try{
MM = (MemberMessage) sInput.readObject();
}catch(IOException e){
break;
} catch (ClassNotFoundException e) {
break;
}
//the message to stop listening for updates
switch(MM.getType()){
case MemberMessage.DISCONECT:
keep = false;
break;
case MemberMessage.UPDATE:
/*
* Update our info in turn
*/
UpdateTest.points = MM.getNumPoints();
UpdateTest.level = MM.getLevel();
try{
//tell the sever we received the info
sOutput.writeObject(new MemberMessage(MemberMessage.RECIEVED, null, -1, null));
}catch(IOException e){
keep = false;
}
break;
}
//*****************************************
}
}
private boolean disconnect() {
System.out.println("Disconectin...");
System.out.println(UpdateTest.username);
System.out.println(UpdateTest.points);
System.out.println(UpdateTest.level);
try{
sOutput.writeObject(new MemberMessage(MemberMessage.DISCONECT, null, -1, null));
}catch(IOException e){
}
// try to close the connection
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {
return false;
}
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {
return false;
}
try {
if(socket != null) socket.close();
}
catch (Exception e) {
return false;
}
return true;
}
}
public static void main(String... args){
updateMember();
getUpdateMember();
}
}
现在,对于服务器:
public class MemberServer {
// a unique ID for each connection
private static int uniqueId;
//ArrayList of connected members
private static ArrayList<Member> ml;
//Arraylist of the Created user profiles
private static ArrayList<String> members = new ArrayList<String>();
//the port to be run on
static private final int PORT = 1520;
//will keep the server running
static private boolean keepGoing;
public MemberServer(){
ml = new ArrayList<Member>();
readUserList();
}
private void readUserList() {
BufferedReader in = null;
try{
in = new BufferedReader(new FileReader("/home/steven/Documents/Android/MemberServerTest/Users.txt"));
String str = in.readLine();
while((str = in.readLine()) != null){
members.addAll(Arrays.asList(str.split(",")));
}
}catch(IOException e){
e.printStackTrace();
}
}
public void begin(){
keepGoing = true;
/*
* Create a socket server and wait for connections
*/
try{
ServerSocket serverSocket = new ServerSocket(1520);
//loop to wait for connections
while(keepGoing){
//message to say that we are waiting
display("Server is waiting for Members on port " + PORT + ".");
Socket socket = serverSocket.accept();// acctep connection
//if asked to stop
if(!keepGoing){
break;
}
Member m = new Member(socket);
ml.add(m);
m.start();
}
try{
serverSocket.close();
for(int i = 0; i < ml.size(); ++i){
Member mb = ml.get(i);
try{
mb.sInput.close();
mb.sOutput.close();
mb.socket.close();
mb.createUserData(mb.username);
}catch(IOException ioE){}
}
}catch(Exception e){}
Writer o = null;
o = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("/home/steven/Documents/Android/MemberServerTest/Users.txt" ), "utf-8"));
o.write("\n");
for(Member k:ml){
o.write(k.username + ",");
}
o.close();
}catch(IOException e){
e.printStackTrace();
}
}
protected static void stop(){
System.out.println("Now Stoping Server...");
keepGoing = false;
try{
new Socket("localhost", PORT);
}catch(Exception e){}
}
private void display(String string) {
System.out.println(string);
}
synchronized static void remove(int id){
for(Member mn: ml){
if(mn.id == id){
ml.remove(mn);
return;
}
}
}
public static void main(String... args){
MemberServer ms = new MemberServer();
ms.begin();
}
class Member extends Thread{
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
public ArrayList<String> properties = new ArrayList<String>();
public int id;
public String username,level = MemberMessage.LEVEL4;
public int numPoints = 0, numUpvotes = 0;
public MemberMessage memMes;
Member(Socket socket){
boolean exists = false;
id = ++uniqueId;
this.socket = socket;
System.out.println("Thread trying to create Object Input/Output Streams");
try{
//create output first
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
//read the username
username = (String) sInput.readObject();
}catch(IOException e){} catch (ClassNotFoundException e) {
e.printStackTrace();
}
for(String str:members){
if(str.equals(username)){
loadUserData();
exists = true;
}
}
if(!exists){
createUserData(username);
}
}
private void createUserData(String username) {
Writer out = null;
try{
out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("/home/steven/Documents/Android/MemberServerTest/" + username + ".txt" ), "utf-8"));
out.write("\nUsername:" + username + ";Points:" + numPoints + ";Level:" + level + ";");
System.out.println("Member data wittem for " + username);
}catch(IOException e){}
finally{
try{
out.close();
}catch(Exception e){}
}
}
private void loadUserData() {
BufferedReader in = null;
try{
in = new BufferedReader(new FileReader("/home/steven/Documents/Android/MemberSeverTest/" + username +".txt"));
String str;
str = in.readLine();
while(( str = in.readLine()) != null){
properties.addAll(Arrays.asList(str.split(";")));
}
in.close();
}catch(IOException e){}
finally{
try{
in.close();
}catch(Exception e){}
}
for(String i:properties){
String[] me = i.split(":");
if(me[0].equals("Username")){
username = me[1];
}else if(me[0].equals("Points")){
numPoints = Integer.parseInt(me[1]);
}else if(me[0].equals("Level")){
level = me[1];
}
}
System.out.println("Member data loaded for " + username);
}
public void run(){
boolean keepGoing = true;
while(keepGoing){
try{
memMes = (MemberMessage) sInput.readObject();
if(memMes != null){
memMes = new MemberMessage(MemberMessage.UPDATE, this.username, this.numPoints, this.level);
}else{
switch(memMes.getType()){
case MemberMessage.UPDATE:
System.out.println("Update message received from " + username);
this.username = memMes.getUsername();
this.numPoints = memMes.getNumPoints();
this.level = memMes.getLevel();
writeToMember(new MemberMessage(MemberMessage.UPDATE, this.username, this.numPoints, this.level));
break;
case MemberMessage.RECIEVED:
System.out.println("Received message recieved from " + username);
writeToMember(new MemberMessage(MemberMessage.DISCONECT, null, -1, null));
break;
case MemberMessage.DISCONECT:
System.out.println("Disconnecting from " + username + "...");
keepGoing = false;
break;
case MemberMessage.UPDATE_REQUEST:
display("GET request from " + username);
writeToMember(new MemberMessage(MemberMessage.UPDATE, this.username, this.numPoints, this.level));
break;
case 100:
System.out.println(memMes.getLevel());
MemberServer.stop();
break;
}
}
}catch(IOException e){keepGoing = false; display("IOException");}
catch (ClassNotFoundException e){keepGoing = false;}
catch(NullPointerException e){
keepGoing = false;
display("NullPointerException");
}catch(Exception e){
e.printStackTrace();
}
}
remove(id);
close();
}
private void writeToMember(MemberMessage j){
try{
sOutput.writeObject(j);
}catch(IOException e){
System.out.println("Error writing to " + username);
e.printStackTrace();
}
}
// try to close everything
private void close() {
createUserData(username);
// 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) {}
}
}
}
您随后的编辑掩盖了这一事实,并且确实使您的文章毫无意义,但是您得到了一个调用readObject的IOException,然后继续,就好像您没有得到它一样,因此您读入的变量仍然为null。不要这样写代码。依赖于readObject调用成功的代码应该与调用一起出现在try块中
当您得到IOException,特别是EOFEException时,您应该关闭套接字并退出读取循环。立即与当前不同。ObjectInputStream,如果使用ObjectOutputStream.writeObject发送空值,则只读返回空值。您必须忽略一个异常。您的异常处理结构肯定非常糟糕。不要在catch块之后编写代码。将其放入try块中。请参阅,确切的异常发生在MemberServer$Member.run方法中的switchmemMes.getType行。在Eclipse中调试时,这会引发NullPointerException,因为memMes=null。现在,正如您所说的,除非客户机发送null,否则这不会发生。那么,为什么我没有发送空值,却收到空值呢@我已经回答了。再看看。不久之前,您遇到了一个IOException,由于您的异常处理结构糟糕,您忽略了它并继续进行。可能是EOFEException。异常处理?这本身就很容易修复;然而,事实是,首先不应该抛出异常,因为PC版本运行时没有异常@EJP也是一个NullPointerException.Look。你得到了一个IOException,你忽略了它并继续,就好像你没有得到它一样。IOException可能是一个EOFEException。如果你知道了,你应该关上插座跳出去。如果有任何其他IOException,同上。打印堆栈跟踪,您就会发现。如果你不这样写代码,你就不会遇到这样的问题。只是争论是没有用的。首先,谢谢你花这么多时间。我真的很感激,即使看起来不是这样。不过,我肯定会调查例外情况。但这就是我所想的:由于服务器与PC版本配合良好,我认为问题在于Android部分。有什么建议吗???
/**
* This class will define the updates to the different properties of a Member object.
* Properties include: usename, #points, and level.
*
*
*/
public class MemberMessage implements Serializable{
protected static final long serialVersionUID = 110L;
public static final int UPDATE = 0, DISCONECT = 1, RECIEVED = 2, UPDATE_REQUEST = 3;
public static final String LEVEL1 = "I'm an expert and I want to help"
,LEVEL2 = "I'm doind okay and I don't need help - but I'm not confident enough to help others."
,LEVEL3 = "I need help"
,LEVEL4 = "I need a tutor because I just can't get the hang of this subject.";
private String username, level;
private int numPoints;
private int type;
public MemberMessage(int type, String username, int numPoints, String level){
this.type = type;
this.username = username;
this.numPoints = numPoints;
this.level = level;
}
public String getUsername(){
return this.username;
}
public int getNumPoints(){
return this.numPoints;
}
public String getLevel(){
return this.level;
}
public int getType(){
return this.type;
}
}