java socket

来源:互联网 发布:注册淘宝企业店铺 编辑:程序博客网 时间:2024/05/06 23:17

SOCKET 解决问题 : 客户端 到 服务端 进行通信(TCP/IP 协议)


客户端 : java.net.Socket client = new Socket("127.0.0.1",80) ; 创建一个链接 IP 127.0.0.1 ,端口号80 的请求链接(底层已经调用connect() )。


服务端 : java.net.ServeSocket serve = new ServeSocket(80) ; 创建一个监听80端口的本地服务( 已经调用blind() )。


客户端与服务端有了 ,那么问题来了: 她们是如何建立连接进行通信(传输数据)的呢


首先对于TCP/IP 协议,大家知道可靠连接是有3次握手的(客户端请求连接允许,服务器端发送允许链接,客户端发送链接请求),相对应的:

1、服务端已经做好客户端请求链接允许的准备:java.net.Socket socket = serve.accept() , serve会一直处于阻塞状态,直到请求来到。 (可简单启动main方法,debug 看程序加载到这行后还往下走么?)

2、客户端请求链接允许 :client.connect() , 如上面讲的,一般初始化的时候就已经connect(),所以不需要我们自己再调用。

3、服务端回复允许链接 : serve.accept()接收到消息,线程继续下走,client端也开始往下走,表示socket已经联通。

4、链接成功,那么通信 : 大家注意步骤一中标红处,serve.accept()返回的是连接的Socket,也就是客户端的socket,这样客户端就可以和服务端进行通信了 。socket有写入写出流进行消息通信 : Socket.getInputStream() 与 Socket.getOutputStream()。客户端和服务端都能使用该Socket的输入输出。


PS : 大家看到网上的例子程序经常会问 new BufferReader(new InputStreamReader(Socket.getInputStream)).readLine()方法为什么可以在客户端有数据的时候才执行 ,因为 BufferReader.readLine()本身是一个阻塞函数,只有在遇到了换行符或者对应流的结束F 才会结束阻塞。


客户端代码 :

package socketTest;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * 客户端用来向Socket的Stream中写入数据
 * 第一个采用一次连接一次输入的例子
 *
 * @author xubo
 *
 */
public class SimpleSocketClient {

    public static void main(String args[]) {
        PrintWriter os = null;
        Socket socket = null;
        try {
            socket = new Socket("127.0.0.1", 4700);// 向本机的4700端口发出客户请求
            BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); // 由系统标准输入设备构造BufferedReader对象
            os = new PrintWriter(socket.getOutputStream()); // 由Socket对象得到输出流,并构造PrintWriter对象
            String readline;
            readline = sin.readLine(); // 从系统标准输入读入一字符串
            while (!readline.equals("bye")) { // 若从标准输入读入的字符串为 "bye"则停止循环
                os.println(URLEncoder.encode(readline, "UTF-8")); // 将从系统标准输入读入的字符串输出到Server
                os.flush(); // 刷新输出流,使Server马上收到该字符串
                System.out.println("Client:" + URLDecoder.decode(readline, "UTF-8"));
                // 从Server读入一字符串,并打印到标准输出上
                readline = sin.readLine(); // 从系统标准输入读入一字符串
            } // 继续循环
            os.close(); // 关闭Socket输出流
            socket.close(); // 关闭Socket
        } catch (Exception e) {
            System.out.println("Error" + e);// 出错,则打印出错信息
        }
    }
}


===================================================================================

服务端代码 :


package socketTest;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;

/**
 * 不适用多线程,简单IO流 Socket通信
 * 输出客户端接收到的数据
 *
 * @author xubo
 */
public class SimpleSocketServe {
    public static void main(String args[]) {
        try {
            ServerSocket server = null;
            try {
                server = new ServerSocket();
                server.bind(new InetSocketAddress(4700)); // 创建一个ServerSocket在端口4700监听客户请求
            } catch (Exception e) {
                System.out.println("can not listen to:" + e); // 出错,打印出错信息
            }
            Socket socket = null;
            BufferedReader is = null;
            try {
                while (true) { // 循环等待
                    socket = server.accept(); // 使用accept()阻塞等待客户请求,有客户求到来则产生一个Socket对象,并继续执行
                    System.out.println("来了个客户端");
                    is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    String ab = null;
                    while ((ab = is.readLine()) != null) { // 持续读取客户端输入的数据,直到客户端关闭流
                        System.out.println("从客户端读取数据:" + URLDecoder.decode(ab, "UTF-8"));
                    }
                    System.out.println("传输数据结束,等待下一个");
                    if (is != null) {
                        is.close();
                    }
                    if (socket != null) {
                        socket.close();
                    }
                }

            } catch (Exception e) {
                System.out.println("Error." + e); // 出错,打印出错信息
            } finally {
                if (is != null) {
                    is.close();
                }
                if (socket != null) {
                    socket.close(); // 关闭Socket
                    server.close(); // 关闭ServerSocket
                }
            }

        } catch (Exception e) {
            System.out.println("Error:" + e);// 出错,打印出错信息
        }
    }
}





0 0
原创粉丝点击