【发布时间】:2014-05-25 07:59:03
【问题描述】:
我正在开发一个聊天客户端应用程序,并且我已经制作了一个服务器。我设法让客户端连接到服务器,但是当我向服务器发送消息时,服务器没有任何反应。
这是我的服务器不工作的部分代码
class ClientConnect implements Runnable {
private DataInputStream in = null;
private DataOutputStream out = null;
Socket client;
ClientConnect(Socket client) {
try {
this.client = client;
/* obtain an input stream to this client ... */
in = new DataInputStream (client.getInputStream());
/* ... and an output stream to the same client */
setOut(new DataOutputStream (client.getOutputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
String msg, response;
ChatServerProtocol protocol = new ChatServerProtocol(this);
try {
while (true) {
if (in.available() > 0){
msg = in.readUTF();
response = protocol.process(msg);
getOut().writeBytes("SERVER: " + response);
}
}
} catch (IOException e) {
System.err.println(e);
} finally {
// The connection is closed for one reason or another
try {
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void sendMsg(String msg) {
try {
getOut().writeBytes(msg);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public DataOutputStream getOut() {
return out;
}
public void setOut(DataOutputStream out) {
this.out = out;
}
}
这里是客户端:
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String response = null;
EditText nicknameField = (EditText)findViewById(R.id.nicknameField);
EditText passwordField = (EditText)findViewById(R.id.passwordField);
nickname = nicknameField.getText().toString();
password = passwordField.getText().toString();
switch(v.getId()){
case R.id.signin:
new SendMessage(this).execute("SIGNUP " + nickname + " " + password );
break;
case R.id.signup:
new SendMessage(this).execute("SIGNUP " + nickname + " " + password );
break;
}
}
private String onPostExecuteSendMessage() {
return null;
}
public void showMessage(String response) {
Builder builder = new AlertDialog.Builder(this);
builder.setMessage(response);
AlertDialog dialog = builder.create();
dialog.show();
}
public void getClientSocket(Socket client) {
this.client = client;
try {
out = new DataOutputStream (client.getOutputStream());
in = new DataInputStream (client.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public DataOutputStream getOut() {
// TODO Auto-generated method stub
return this.out;
}
public DataInputStream getIn() {
// TODO Auto-generated method stub
return this.in;
}
public void goMenuChat() {
// TODO Auto-generated method stub
Intent intent = new Intent(this, MenuChatActivity.class);
startActivity(intent);
}
}
我还使用 Asynctask 从客户端发送消息:
package client.chatclient;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import android.os.AsyncTask;
public class SendMessage extends AsyncTask<String, String, String> {
private static final String msg_OK = "OK";
private static final String msg_NICK_IN_USE = "NICK IN USE";
private static final String msg_UNKNOWN_CMD = "UNKNOWN CMD";
private static final String msg_INVALID = "INVALID COMMAND";
private static final String msg_SEND_FAILED = "FAILED TO SEND";
private static final String msg_INCORRECT_IDS = "INCORRECT IDS";
private static final String msg_DISCONNECT = "DISCONNECT";
private WeakReference<MainActivity> activity;
private String message;
private String response = "";
private DataOutputStream out;
private DataInputStream in;
public SendMessage(MainActivity act){
super();
activity = new WeakReference<MainActivity>(act);
}
protected String doInBackground(String... message) {
this.message = message[0];
this.out = activity.get().getOut();
this.in = activity.get().getIn();
try {
out.writeBytes(this.message);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response = convertStreamToString(this.in);
return response;
}
protected void onPostExecute(String response) {
if ((response == msg_INCORRECT_IDS) || (response == msg_NICK_IN_USE)){
activity.get().showMessage(response);
}
else if (response == msg_OK){
activity.get().goMenuChat();
}
}
private static String convertStreamToString(DataInputStream in) {
/*
* To convert the InputStream to String we use the
* BufferedReader.readLine() method. We iterate until the BufferedReader
* return null which means there's no more data to read. Each line will
* appended to a StringBuilder and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
我通过单击一个按钮从客户端发送我的消息,然后它转到 SendMessage 类,并将消息发送到服务器,通常服务器应该在循环“while (true)...”中接收我的消息并根据我实现的协议发回响应。
我真的不知道出了什么问题。如果您知道如何解决此问题或有一些解决方案,请告诉我!如果您想了解更多详细信息,请询问我! :)
非常感谢!
编辑:
我在这里实例化了我的 ClientConnect
public class ChatServer {
private static int port = 8080;
public static void main (String[] args) throws IOException {
ServerSocket server = new ServerSocket(port); /* start listening on the port */
System.out.println( "Listening on "+ server );
Socket client = null;
while(true) {
try {
client = server.accept();
System.out.println( "Connection from " + client );
/* start a new thread to handle this client */
Thread t = new Thread(new ClientConnect(client));
t.start();
} catch (IOException e) {
System.err.println("Accept failed.");
System.err.println(e);
System.exit(1);
server.close();
}
}
}
}
编辑:我发现问题出在哪里。正如你所说,我放了一些 log() 语句
log.d(null,"beforeconvert")
try {
log.d(null,"convert")
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
log.d(null,"errorconvert")
e.printStackTrace();
}
在 logcat 之后,它只显示“beforeconvert”。我真的不知道问题是什么? while ((line = reader.readLine()) != null) 肯定是问题所在。当我在eclipse中逐步使用调试器时,它停在这一行,甚至没有进入循环。
编辑:我真的不知道为什么,但是当我在运行我的应用程序时退出模拟器时,它会显示所有内容。
Listening on ServerSocket[addr=0.0.0.0/0.0.0.0,localport=8080]
Connection from Socket[addr=/127.0.0.1,port=56646,localport=8080]
client connected
msg received
error !
SIGNUP Nickname Password
SIGNUP Nickname Password
msg converted
OK
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at server.ClientConnect.convertStreamToString(ChatServer.java:357)
at server.ClientConnect.run(ChatServer.java:304)
at java.lang.Thread.run(Unknown Source)
java.net.SocketException: Connection reset by peer: socket write error
【问题讨论】:
-
添加一些 Log() 语句,以便您/我们可以看到服务器走了多远。将它们也放在捕获块中。展示您如何实例化/调用 ClientConnect。
-
我的问题可能来自 while ((line = reader.readLine()) != null) { 我是否正确使用了 readLine 方法?
-
您的服务器没有发送任何内容。因此,您的客户无需阅读任何内容。