java socket实现全双工通信
java socket实现全双工通信
单工、半双工和全双工的定义
如果在通信过程的任意时刻,信息只能由一方A传到另一方B,则称为单工。
如果在任意时刻,信息既可由A传到B,又能由B传A,但只能由一个方向上的传输存在,称为半双工传输。
如果在任意时刻,线路上存在A到B和B到A的双向信号传输,则称为全双工。
用swing 做的简单界面 实现了客户端和服务器端全双工通信。
Server端代码:
package cn.cblue.net1; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; /** * @Description: 服务端 * @author huangzjb cblue2013@126.com * @Company Digital China * @date 2014-6-4 下午02:18:06 * @version 1.0 */ public class MyServer extends JFrame implements ActionListener { JTextArea jta = null; JTextField jtf = null; JButton jb = null; JPanel jp1 = null; JScrollPane jsp = null; PrintWriter pw = null; public static void main(String[] args) { new MyServer(); } public MyServer() { jta = new JTextArea(); jsp = new JScrollPane(jta); jtf = new JTextField(10); // 注册回车事件 jtf.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { sendMessage(); } } }); jb = new JButton("发送"); jb.addActionListener(this);// 注册一个监听事件 jp1 = new JPanel(); jp1.add(jtf); jp1.add(jb); this.add(jsp, BorderLayout.CENTER); this.add(jp1, BorderLayout.SOUTH); this.setTitle("chat server"); this.setSize(300, 200); this.setVisible(true); // 接收从客户端发送过来的消息 try { ServerSocket ss = new ServerSocket(2222); Socket s = ss.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(s .getInputStream())); pw = new PrintWriter(s.getOutputStream(), true);// 写成pw = new PrintWriter(s.getOutputStream())会有问题 while (true) { String info = in.readLine(); String str = null; if (jta.getText() == null || "".equals(jta.getText())) { str = "Server:" + info; } else { str = jta.getText() + "\r\nServer:" + info; } jta.setText(str); jta.setCaretPosition(jta.getDocument().getLength()); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } // 把信息给客户端 @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if (e.getSource() == jb) { sendMessage(); } } /** * @Description: 发送消息给客户端 * @throws */ public void sendMessage() { String info = jtf.getText(); pw.println(info); pw.flush(); jtf.setText(""); if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Client:" + info); } else { jta.append("\r\nClient:" + info); } jta.setCaretPosition(jta.getDocument().getLength());// 设置滚动条自动滚动 } }
Client端代码:
package cn.cblue.net1; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; /** * @Description: 客户端 * @author huangzjb cblue2013@126.com * @Company Digital China * @date 2014-6-4 下午02:18:24 * @version 1.0 */ public class MyClient extends JFrame implements ActionListener { JTextArea jta = null; JTextField jtf = null; JButton jb = null; JPanel jp1 = null; JScrollPane jsp = null; PrintWriter pw = null; public static void main(String[] args) { new MyClient(); } public MyClient() { jta = new JTextArea(); jsp = new JScrollPane(jta); jtf = new JTextField(10); // 注册回车事件 jtf.addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { sendMessage(); } } }); jb = new JButton("发送"); jb.addActionListener(this);// 注册一个监听事件 jp1 = new JPanel(); jp1.add(jtf); jp1.add(jb); this.add(jsp, BorderLayout.CENTER); this.add(jp1, BorderLayout.SOUTH); this.setTitle("chat client"); this.setSize(300, 200); this.setVisible(true); // 接收从服务端发送过来的消息 try { Socket s = new Socket("127.0.0.1", 2222); BufferedReader in = new BufferedReader(new InputStreamReader(s .getInputStream())); pw = new PrintWriter(s.getOutputStream(), true); while (true) { String info = in.readLine(); String str = null; if (jta.getText() == null || "".equals(jta.getText())) { str = "Server:" + info; } else { str = jta.getText() + "\r\nServer:" + info; } jta.setText(str); jta.setCaretPosition(jta.getDocument().getLength()); } } catch (IOException e) { e.printStackTrace(); } } // 把信息给服务器端 @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == jb) { sendMessage(); } } /** * @Description: 发送消息给服务器端 * @throws */ public void sendMessage() { String info = jtf.getText(); pw.println(info); pw.flush(); jtf.setText(""); if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Client:" + info); } else { jta.append("\r\nClient:" + info); } jta.setCaretPosition(jta.getDocument().getLength());// 设置滚动条自动滚动 } }