Socket中InputStream的read方法的阻塞特性

用java,搞通信一定会接触到Socket,ServerSocket这2个类,基本使用非常简单,但如果想良好的控制,还是得小心之非常啊.因为Socket中InputStream的read()当管道无数据时便等待数据的填充,但OutputStream可以继续写入数据.如果这点搞清楚了,就没多大的问题了, 
read()阻塞后,继续想服务器提交数据,read()方法便会读出服务器的响应数据来. 
此次便是记录下,如何比较随心的使用java的Socket. 
2个类, 

TCPServer 

package org.sk.lib.socket;  
  
import java.io.IOException;  
import java.io.PrintStream;  
import java.net.ServerSocket;  
import java.net.Socket;  
import java.util.Scanner;  
  
public class TCPServer {  
    private ServerSocket server;  
    private Socket client;  
      
    public TCPServer(int port) throws IOException {  
        // TODO Auto-generated constructor stub  
        server = new ServerSocket(port);  
    }  
    /** 
     * 开始tcp的服务 
     * @throws IOException 
     */  
    public void start() throws IOException{  
        while(true){  
            client = server.accept();  
            new Thread(new ClientThread(client)).start();  
        }  
    }  
    public static void main(String[] args) throws IOException {  
        new TCPServer(1234).start();  
    }  
    /** 
     * 客户端处理 
     * @author Ozone 
     * 
     */  
    class ClientThread implements Runnable{  
        private Socket client;  
        private Scanner in;  
        private PrintStream out;  
          
        public ClientThread(Socket client) throws IOException {  
            // TODO Auto-generated constructor stub  
            this.client = client;  
            in = new Scanner(client.getInputStream());  
            out = new PrintStream(client.getOutputStream());  
        }  
        public void run() {  
            // TODO Auto-generated method stub  
            try {  
                blockProcess();  
            } catch (IOException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
        /*** 
         * 处理客户端的请求,一条一条的进行处理,每次接收1行指令,指令以\n为结束 
         * @throws IOException 
         */  
        private void blockProcess() throws IOException{  
            String line;  
            while(in.hasNextLine()){  
                line = in.nextLine();  
                if(line.equals("bye")){  
                    out.println("bye");  
                    break;  
                }  
                {  
                    //需要进行处理  
                    System.out.println(line);  
                    out.println("a\nb\nc\nd");  
                }  
            }  
            in.close();  
            out.close();  
            client.close();  
        }  
    }  
}  

TCPClient: 

package org.sk.lib.socket;  
  
import java.awt.BorderLayout;  
import java.awt.event.ActionEvent;  
import java.awt.event.ActionListener;  
import java.io.IOException;  
import java.io.PrintWriter;  
import java.net.Socket;  
import java.net.UnknownHostException;  
import java.util.Scanner;  
  
import javax.swing.JButton;  
import javax.swing.JFrame;  
import javax.swing.JTextArea;  
  
  
public class TCPClient {  
      
    private Socket client;  
    private PrintWriter out;  
    private Scanner in;  
      
    public TCPClient(String addr, int port) throws UnknownHostException,  
            IOException {  
        client = new Socket(addr, port);  
        in = new Scanner(client.getInputStream());  
        out = new PrintWriter(client.getOutputStream(),true);  
    }  
    //初始化 一个窗体  
    public void initFrame() {  
        JFrame frame = new JFrame();  
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        frame.setSize(400, 300);  
        frame.setVisible(true);  
        final JTextArea ta = new JTextArea();  
        frame.add(ta, BorderLayout.NORTH);  
        JButton bt = new JButton("go");  
        frame.add(bt, BorderLayout.CENTER);  
        frame.pack();  
        bt.addActionListener(new ActionListener() {  
  
            public void actionPerformed(ActionEvent e) {  
                // TODO Auto-generated method stub  
                if(!ta.getText().equals(""))  
                    send(ta.getText());  
            }  
        });  
    }  
    /** 
     * 将数据发送至 输出流 
     * @param cont 
     */  
    private void send(String cont){  
        out.println(cont);  
    }  
    /*** 
     * 处理客户端的读取操作 
     * 1 当管道内无数据(服务器无响应)便阻塞. 
     * 2 管道内有多行数据,便一直读取到完, 
     * 1,2 循环,直到收到服务器的bye字符,连接关闭,会话结束 
     * @throws IOException 
     */  
    public void registerListener() throws IOException {  
        String line;  
        while (in.hasNextLine()) {  
            line = in.nextLine();  
            if(line.equals("bye")){  
                break;  
            }  
            //处理服务器响应  
            System.out.println(line);  
        }  
        in.close();  
        out.close();  
        client.close();  
        System.out.println("连接关闭");  
    }  
  
    public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {  
        TCPClient client = new TCPClient("127.0.0.1",1234);  
        client.initFrame();  
        client.registerListener();  
    }  
}  

启动TCPServer,之后运行TCPClicent,在小窗口中输入字符,bye退出.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值