我有一个服务器/客户端应用程序,用于发送/接收有关应用程序用户(成员)的更新。不幸的是,当Android设备上的客户端发送任何getUpdate / sendUpdate对象时,服务器会将它们作为空接收。
我还有一个PC版的Android客户端,完全正常。它有相同的方法和一切。
以下是Android设备上的客户端:
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) {}
}
}
}
现在,我看到的问题是调用sOutput.wirteObject(mh)的实际sendUpdate()方法。在服务器端,此发送对象被接收为null。服务器连接的方式是它接受套接字连接,创建一个成员对象来处理IO,然后侦听任何incomming MemberMessage对象。收到MemberMessage时会出现问题;但是,它的值为null。
任何想法? 先谢谢你的帮助!
此外,还有MemberMessage类:
/**
* 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;
}
}
答案 0 :(得分:0)
你的后续编辑模糊了这个事实,确实让你的帖子毫无意义,但你得到IOException
来电readObject()
然后继续,好像你没有得到它,所以变量你读入仍为空。不要写这样的代码。依赖于readObject()调用成功的代码应该与调用一起位于try块中。
当你得到IOException
,特别是EOFException
时,你应该关闭套接字并退出读取循环。立即。不像现在那样。