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() {@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic 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 blocke.printStackTrace();}}// 把信息给客户端@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif (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() {@Overridepublic void keyTyped(KeyEvent e) {}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic 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();}}// 把信息给服务器端@Overridepublic 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());// 设置滚动条自动滚动}}