之前实现了服务器与客户端的单项通信,现在来实现双向通信,这里其实就是加了一个线程,因为调用read()方法的时候会产生阻塞;所以要调用线程。下面上代码,在代码里有注释。在代码里说明会好一点。
- 客户端代码
//这个模块里主要是要显示出客户端界面
public class DrawClient {
public void showUI() {
JFrame jf = new JFrame();
jf.setSize(400, 300);
jf.setTitle("客户端 Meetting by gzh4869--0.1");
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(3);
//流式布局
FlowLayout fl = new FlowLayout();
jf.setLayout(fl);
JButton jub = new JButton("发送");
jf.add(jub);
JTextField jtf = new JTextField(20);
jf.add(jtf);
JTextArea jea = new JTextArea(10, 30);
jf.add(jea);
jf.setVisible(true);
ConnClient cc = new ConnClient(jea);
//cc.Conn()就是判断是否连接成功
if (cc.Conn()) {
cc.start();//在这里启动线程,假设不用线程,那就会用到read()方法,那么程序就会阻塞,无法向下执行,所以这里要用线程
System.out.println("成功接入线程");
jub.addActionListener(new ActionListener() {
String s;
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method st
try {
//将文本框内容发送之后在清零
s = jtf.getText();
cc.ops.write(s.getBytes());
jtf.setText("");//清零
System.out.println("客户端发送成功");
} catch (Exception ef) {
ef.printStackTrace();
}
}
});
}
}
public static void main(String[] args) {
DrawClient dc = new DrawClient();
dc.showUI();
}
}
//这个模块主要是用来判断客户端代码是否连接成功
public class ConnClient extends Thread {
InputStream ips;
OutputStream ops;
JTextArea jea;
public ConnClient(JTextArea jea) {
this.jea = jea;
}
public void run() {
System.out.println("线程开始执行");
int len = 0;
byte[] buf = new byte[1024];
System.out.println("1");
try {
while ((len = ips.read(buf)) != -1) {
String s2 = new String(buf);
System.out.println(s2);
jea.append(s2+"\r\n");//这里最好用append(),如果用setText();新的内容会将老的内容覆盖掉
}
System.out.println("客户端接收成功");
ips.close();
} catch (Exception ef) {
ef.printStackTrace();
}
}
//判断是否连接成功
public boolean Conn() {
try {
Socket st = new Socket("127.0.0.1", 4578);
System.out.println("连接成功");
// 输入输出流
ips = st.getInputStream();
ops = st.getOutputStream();
return true;
} catch (Exception ef) {
ef.printStackTrace();
}
return false;
}
}
-
服务器端代码
-
因为这里消息是互通的,所以服务器端代码和客户端代码差不多,因为是双向的消息传递也要用到线程
public class ConnServer extends Thread {
InputStream ips;
OutputStream ops;
JTextArea jea;
JTextField jtf;
public ConnServer(JTextArea jea,JTextField jtf) {
this.jea = jea;
this.jtf = jtf;
}
public void run() {
int len;
byte[] buf = new byte[1024];
try {
while ((len = ips.read(buf)) != -1) {
String s2 = new String(buf);
System.out.println(s2);
jea.append(s2+"\r\n");;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("服务器接收成功");
}
//服务器与客户端是否连接
public boolean Conn() {
try {
ServerSocket sst = new ServerSocket(4578);
Socket st = sst.accept();
System.out.println("连接成功");
// 输入输出流
ips = st.getInputStream();
ops = st.getOutputStream();
return true;
} catch (Exception ef) {
ef.printStackTrace();
}
return false;
}
}
public class DrawServer {
public void showUI() {
JFrame jf = new JFrame();
jf.setSize(400, 300);
jf.setTitle("服务器 Meetting by gzh4869--0.1");
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(3);
FlowLayout fl = new FlowLayout();
jf.setLayout(fl);
JTextField jtf = new JTextField(20);
jf.add(jtf);
JButton jub = new JButton("发送");
jf.add(jub);
JTextArea jea = new JTextArea(10, 30);
jf.add(jea);
jf.setVisible(true);
ConnServer cs = new ConnServer(jea,jtf);
if (cs.Conn()) {
cs.start();
jub.addActionListener(new ActionListener() {
String s;
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
s = jtf.getText();
try {
cs.ops.write(s.getBytes());
System.out.println("服务器发送成功");
jtf.setText("");
//cs.ops.close();
}catch(Exception ef) {
ef.printStackTrace();
}
}
});
}
}
public static void main(String[] arg) {
DrawServer ds = new DrawServer();
ds.showUI();
}
}
- 效果