Socket基础概念

1、本地控制台的标准输入输出

EchoPlayer.java
字符流需要字节流转换
System.in提供控制台输入流
BufferedReader提供了字符流一行的读取
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
public class EchoPlayer {

    public String echo(String msg){
        return "echo:"+msg;
    }

    public void talk() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String msg = null;
        while((msg = br.readLine())!=null){
            System.out.println(echo(msg));
            if(msg.equals("bye")){
                break;
            }
        }
    }

    public static void main(String[] args) throws IOException {
        new EchoPlayer().talk();
    }

}

 

2、简易客户端服务端通信

EchoServer.java
通过ServerSocket创建服务端监听
当accept()方法监听客户端连接返回Socket
根据Socket获取输入输出流

new PrintWriter(socketOut,true);
true表示覆盖前面的内容
PrintWriter内部封装了new BufferedWriter(new OutputStreamWriter(out))

输入流
InputStream socketIn = socket.getInputStream();
return new BufferedReader(new InputStreamReader(socketIn));
输出流
OutputStream socketOut = socket.getOutputStream();
return new PrintWriter(socketOut,true);

EchoClient.java
通过创建Socket建立服务端连接
public class EchoServer {
    private int port = 8000;
    private ServerSocket serverSocket;

    public EchoServer() throws IOException {
        serverSocket = new ServerSocket(port);
        System.out.println("服务器启动");
    }

    public String echo(String msg){
        return "echo:"+msg;
    }

    private PrintWriter getWriter(Socket socket) throws IOException {
        OutputStream socketOut = socket.getOutputStream();
        return new PrintWriter(socketOut, true);
    }

    private BufferedReader getReader(Socket socket) throws IOException{
        InputStream socketIn = socket.getInputStream();
        return new BufferedReader(new InputStreamReader(socketIn));
    }

    public void service(){
        while(true){
            Socket socket = null;
            try {
                socket = serverSocket.accept();
                System.out.println("一个新的客户端连接:"+socket.getInetAddress()+":"+socket.getPort());
                BufferedReader br = getReader(socket);
                PrintWriter pw = getWriter(socket);

                String msg = null;
                while((msg=br.readLine())!=null){
                    System.out.println(msg);
                    pw.println(echo(msg));// 将接收到的消息再写回去
                    if(msg.equals("bye")){
                        break;
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally{
                if(socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }


    public static void main(String[] args) throws IOException {
        new EchoServer().service();
    }
}

  

public class EchoClient {
    private String host = "localhost";
    private int port = 8000;
    private Socket socket;

    public EchoClient() throws IOException {
        socket = new Socket(host, port);
    }

    private PrintWriter getWriter(Socket socket) throws IOException {
        OutputStream socketOut = socket.getOutputStream();
        return new PrintWriter(socketOut, true);
    }

    private BufferedReader getReader(Socket socket) throws IOException {
        InputStream socketIn = socket.getInputStream();
        return new BufferedReader(new InputStreamReader(socketIn));
    }

    public void talk(){
        try {
            BufferedReader br = getReader(socket);
            PrintWriter pw = getWriter(socket);
            BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
            String msg = null;
            while((msg=localReader.readLine())!= null){
                pw.println(msg);
                System.out.println(br.readLine());
                if(msg.equals("bye")){
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public static void main(String[] args) throws IOException {
        new EchoClient().talk();
    }
}

 

3、判断端口是否被服务器程序监听

PortScanner.java
创建Socket,如果能够建立连接表示被监听

 

public class PortScanner {
    public void scan(String host){
        Socket socket = null;
        for(int port=1;port<1024;port++){
            try {
                socket = new Socket(host, port);
                System.out.println("There is aserver on port"+port);
            } catch (IOException e) {
                System.out.println("Can't connect to port"+port);
            } finally {
                if(socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
    }


    public static void main(String[] args){
        String host = "localhost";
        if(args.length>0)host = args[0];
        new PortScanner().scan(host);
    }
}

 

4、Socket常见异常

ConnectTester.java
javac编译需要到包下,编译不用包名
java运行不用到包下,需要包名
C:\Users\Administrator\Desktop\Socket\socket2\src\main\java>java com.example.ConnectTester www.baidu.com 80
www.baidu.com/180.97.33.108:80 : 16ms

UnknownHostException 无法识别主机的名字或IP地址
ConnectException 没有服务器进程监听指定端口(未试成功)或服务器进程拒绝连接
server:
ServerSocket serverSocket = new ServerSocket(8000,2); //连接请求队列的长度为2
Thread.sleep(360000); //睡眠6分钟
client:
Socket s1 = new Socket("localhost",8000);
System.out.println("第一次连接成功");
Socket s2 = new Socket("localhost",8000);
System.out.println("第二次连接成功");
Socket s3 = new Socket("localhost",8000);
System.out.println("第三次连接成功");

SocketTimeoutException 连接超时
BindException 无法绑定指定的本地IP地址或端口
public class ConnectTester {
    public void connect(String host, int port){
        SocketAddress remoteAddr = new InetSocketAddress(host, port);
        Socket socket = null;
        String result = "";
        try {
            long begin = System.currentTimeMillis();
            socket = new Socket();
            socket.connect(remoteAddr, 1000);// 连接超时时间
            long end = System.currentTimeMillis();
            result = (end-begin)+"ms";
        }catch (BindException e) {
            result="Local address and port can't be binded";
        }catch (UnknownHostException e) {
            result="Unknown Host";
        }catch (ConnectException e) {
            result="Connection Refused";
        }catch (SocketTimeoutException e) {
            result="TimeOut";
        }catch (IOException e) {
            result="failure";
        } finally {
            try {
                if(socket!=null)socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println(remoteAddr+" : "+result);
    }


    public static void main(String[] args){
        String host = "localhost";
        int port = 25;
        if(args.length>1){
            host = args[0];
            port = Integer.parseInt(args[1]);
        }
        new ConnectTester().connect(host, port);
    }
}

 

5、模拟HTTP

HTTPClient.java
Socket建立连接,写与读数据
接收数据可用字节数组输出流暂存数据
接收的socket输入流写入字节数组输出流
InputStream socketIn = socket.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] buff = new byte[1024];
int len;
while((len=socketIn.read(buff))!=-1){
buffer.write(buff, 0, len);
}
System.out.println(new String(buffer.toByteArray()));

半关闭Socket
shutdownInput()关闭输入流
shutdownOutput()关闭输出流
public class HTTPClient {

    String host = "www.javathinker.org";
    int port = 80;
    Socket socket;

    public void createSocket() throws IOException {
        socket = new Socket(host, port);
    }

    public void communicate() throws IOException {
        StringBuffer sb=new StringBuffer();
        // sb.append("\"GET \"+\"/index.jsp\"+\" HTTP/1.1\\r\\n\"");
        sb.append("Host: "+host+"\r\n");
        sb.append("Accept: */*\r\n");
        sb.append("Accept-Language: zh-cn\r\n");
        sb.append("Accept-Encoding: gzip, deflate\r\n");
        sb.append("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n");
        sb.append("Connection: Keep-Alive\r\n\r\n");

        // 发出HTTP请求
        OutputStream socketOut = socket.getOutputStream();
        socketOut.write(sb.toString().getBytes());
        /*// 关闭输出流*/
        socket.shutdownOutput();

        // 接收响应
        InputStream socketIn = socket.getInputStream();
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        byte[] buff = new byte[1024];
        int len;
        while((len=socketIn.read(buff))!=-1){
            buffer.write(buff, 0, len);
        }
        System.out.println(new String(buffer.toByteArray()));

        socket.close();
    }


    public static void main(String[] args) throws IOException {
        HTTPClient client = new HTTPClient();
        client.createSocket();
        client.communicate();
    }

}

  

 

 

 

  

posted @ 2016-06-23 09:33  轻云沉峰  阅读(184)  评论(0)    收藏  举报