最近在写一个基于Socket的聊天室,部分内容如下:将一个对象以对象流的形式从客户端发送到服务端,在服务端解接收对象并打印内容。怎么样,是不是很简单,没错,就是这么简单的东西硬是花了我两个小时改bug。。。
先定义1个对象类User
package com.common;
public class User implements java.io.Serializable {
private String uid;
private String pwd;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public User(String uid, String pwd) {
this.uid = uid;
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"uid='" + uid + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
然后是客户端代码
package com.server.model;
import com.client.view.FriendList;
import com.common.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class TestClient {
public static void main(String[] args) {
try {
Socket client = new Socket("localhost",9999);
ObjectOutputStream output = new ObjectOutputStream(client.getOutputStream());
ObjectInputStream input = new ObjectInputStream(client.getInputStream());
User u = new User("111","aaa");
output.writeObject(u);
System.out.println("OK");//发送之后输出“OK”
} catch (IOException e) {
System.out.println("客户端连接失败");
e.printStackTrace();
}
}
}
接着是服务器代码
package com.server.model;
import com.common.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(9999);
//2.阻塞式等待客户端连接 (返回值)Socket accept()侦听要连接到此套接字的客户端并接受它。
Socket client = server.accept();
System.out.println("一个客户端已连接....");
ObjectInputStream input = new ObjectInputStream(client.getInputStream());
ObjectOutputStream output = new ObjectOutputStream(client.getOutputStream());
User u = (User) input.readObject();
System.out.println(u.toString());
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器启动失败!");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
其实很简单,创建一个uid=111,pwd="aaa"的对象,发送到服务器,输出“OK”,服务器接收对象并调用其toString()方法输出,但结果是客户端能连接到服务器,之后就没有然后了,也就是说服务器端只输出了“一个客户端已连接”,并没有接收到客户端发来的数据,客户端也没有输出“OK”,这我就郁闷了,明明能连接上,为什么就发不过去呢,我尝试换了个端口号,结果还是这样。
可能有人会说,你客户端只是发送数据为什么要获取输入流,你服务器只是接收数据为什么要获取输出流,其实实际情况是客户端之后会接收数据,服务器也会会用客户端数据,只是被我把这部分代码注释了,但这也给了我一个思路,既然没用,不如去掉,没想到,这去掉之后真的直接成功了。
经过一系列尝试改进之后,我发现服务器端不用删代码也能成功,真正的问题是客户端这两行代码的先后问题,
ObjectOutputStream output = new ObjectOutputStream(client.getOutputStream());
ObjectInputStream input = new ObjectInputStream(client.getInputStream());
我觉得这有点扯淡,但事实就是这样,当input语句在output语句之后执行时,没有任何问题,但是顺序颠倒就是失败,试了好几次都是这样,我不知道这是什么原因,但还是觉得记下来比较好,万一哪天又碰到这种奇葩问题,就能解决了。
最后说一句,我在写完这篇博客后又去试了一次把input语句放在output语句之前,没想到啊没想到,这次竟然成功了,我都想摔了了这电脑了,看了看写了这么长的博客,唉,还是算了吧,不删了,希望大家看完之后不要打我,我先溜了,有什么想法可以留言,哈哈哈哈。。
打赏

