Java 套接字

起因

其实我不想写起因,一位面试人家让我写一个套接字,不会,输入输出,不会写。唉。。。 写代码吧,现在想想,我认真写java代码也没多久,慢慢来呗;

套接字

这个怎么理解呢,就是说tcp/udp在运输层,那么上层好多应用都要使用TCP,那么怎么区分呢?这时候就出现了套接字和端口,应用程序自己创建套接字,标记自己的端口,那么分包的时候就有了约束,传回的数据包,也可以根据端口找到位置;代码传送门

Demo时间

下面会有很多Demo 主要参考了 参考一参考二,主要参考;

Demo1

客户端获取服务器发过来的信息,然后就完了;

public class TestClient {
    public static void main(String args[]) {
        try {
            // 创建socket对象,指定服务器的ip地址,和服务器监听的端口号
            // 客户端在new的时候,就发出了连接请求,服务器端就会进行处理,如果服务器端没有开启服务,那么
            // 这时候就会找不到服务器,并同时抛出异常==》java.net.ConnectException: Connection
            // refused: connect
            Socket s1 = new Socket("127.0.0.1", 8888);
            // 打开输入流
            InputStream is = s1.getInputStream();
            // 封装输入流
            DataInputStream dis = new DataInputStream(is);
            // 打印服务器端发送过来的信息
            System.out.println(dis.readUTF());
            System.out.println(dis.readUTF());
            // 关闭输入流
            dis.close();
            // 关闭打开的socket对象
            s1.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public class TestServer {
    public static void main(String args[]) {
        try {
            // 指定服务器端的端口号为8888
            ServerSocket s = new ServerSocket(8888);
            while (true) {
                // 建立连接
                Socket socket = s.accept();
                // 打开输出流
                OutputStream os = socket.getOutputStream();
                // 封装输出流
                DataOutputStream dos = new DataOutputStream(os);
                // s<li>.getInetAddress()获取远程ip地址,s<li>.getPort()远程客户端的端口号
                // 向客户端发送数据
                dos.writeUTF("你好,客户端地址信息: " + socket.getInetAddress()
                        + "\t客户端通信端口号: " + socket.getPort());
                dos.writeUTF("i'm a server ,my name is colin!");
                // 关闭打开的输出流
                dos.close();
                // 关闭打开的socket对象
                socket.close();
            }// 开始下一此循环
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

题外话:

我们很容易服务器和客户端的形式基本类似这样:

 ServerSocket s = new ServerSocket(8888);
            while (true) {
                Socket socket = s.accept();
                /*stream的部分
                */
                /*关闭流,关闭连接之类的
                */
            }

socket如果接收不到,服务器就会就等着;
将其放在while(true)中,就一直监听;上一个关掉,监听下一个;

Socket socket = s.accept();

对于流来说,这里就很麻烦,一会儿就被绕晕了;输入,输出到底是针对谁来说的呢?
首先我们要清楚读和写;很简单吧,正因为简单,所以我就被弄糊涂了;
考虑我们在纸上写字;我们就将其简化为写;
然后我们抄写一遍,我们就需要先读出来,然后在写下;
这里我们会很容易想到我们写,我们读的;主题对象是我们;

但是考虑我们现在在敲代码;写是肯定的。但是真的在写吗?这是一个问题啊;我们通过键盘输入一段字符,字节流,给了机器,很明显的输入流对比,但是对系统来说,他是读的啊,他得知道你敲了啥啊;

所以输入流是这样一种对象: 读入你的输入,并且已相应的的格式,编码读给系统; 举个例子,大家来学校报道,报道通道相当于一个输入流,不断地来人,报道哪里会有人看你的档案,哦,你叫张三,然后学校知道你叫做张三;这就是输入流做的事情;

翻过来输出流,相当于什么呢?大家毕业了,排着队去照毕业照;不断地人流,到了照相馆照相;咔咔咔,大家就被输出了;这样不生动,我们换成劳动力市场,学校作为主体,输入流就是毕业时一个一个下发的档案,然后大家就可以去找工作了;学校就不管你了,你被输出了;

DEMO2

客户端一直说,服务器一直听;

public class Client {
    Socket client;

    public Client() {
        try {
            client = new Socket("localhost", 7777);
            OutputStream outputStream = client.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
            InputStreamReader inputStreamReader = new InputStreamReader(System.in);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String a;
            while (true) {
                a = bufferedReader.readLine();
                if (a.equals("bye"))
                    break;
                dataOutputStream.writeUTF(a);
            }
            dataOutputStream.close();
            bufferedReader.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {

            new Client();

    }
public class Server {
    private Socket socket;
    private ServerSocket ss;

    public Server() throws IOException {
        ss = new ServerSocket(7777);
        socket = ss.accept();
        InputStream inputStream = socket.getInputStream();
        DataInputStream dataInputStream = new DataInputStream(inputStream);
        while (true) {
            String a = dataInputStream.readUTF();
            if (a.equals("bye"))
                break;
            System.out.println(a);
            br.readLine());

        }

    }

    public static void main(String[] args) {
        try {
            new Server();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里我们发现一个socket一边写,一边读,像不像是只是一个文件呢?

Demo3

客户端和服务器必须一人一句

public class TestClient {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("localhost",8888);
            OutputStream outputStream = socket.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

            InputStream inputStream = socket.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(inputStream);

            InputStreamReader inputStreamReader = new InputStreamReader(System.in);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String info;
            String info1;

            while (true)
            {
                info = bufferedReader.readLine();
                dataOutputStream.writeUTF(info);

                if (info == "bye")
                    break;
                info1 = dataInputStream.readUTF();

                System.out.println("服务器"+info1);
                if (info1 == "bye")
                    break;
            }
            bufferedReader.close();
            dataInputStream.close();
            dataOutputStream.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class TestServer {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket socket = serverSocket.accept();
            OutputStream outputStream = socket.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
            InputStream inputStream = socket.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            InputStreamReader inputStreamReader = new InputStreamReader(System.in);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String info;
            String info1;
            while (true)
            {
                info = dataInputStream.readUTF();
                System.out.println("客户端说:"+ info);
                if (info.equals("bye"))
                    break;
                info1 = bufferedReader.readLine();
                dataOutputStream.writeUTF(info1);
                if (info1.equals("bye"))
                    break;
            }
            dataInputStream.close();
            dataOutputStream.close();
            bufferedReader.close();
            socket.close();
            serverSocket.close();
        } catch (SocketException e)
        {
            System.out.println("网络异常");
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}

其实这里我们就发现,这其实就是典型的一个TCP的连接了,一个一直监听,一个需要找到正确的ip和端口,才能正确获得socket;

Demo4

其实就是两个线程,一个读,一个写;像不像一个棉花,可以随时咬一口,或者随时放一块;

public class TestClient {
    public static void main(String[] args) {
        try {

            Socket socket = new Socket("localhost",8888);

            InputStream inputStream = socket.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(inputStream);
            OutputStream outputStream = socket.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

            new MyClientReader(dataInputStream).start();
            new MyClientWriter(dataOutputStream).start();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class MyClientReader extends  Thread{
    private DataInputStream dataInputStream;


    public MyClientReader(DataInputStream dataInputStream) {
        this.dataInputStream = dataInputStream;
    }

    @Override
    public void run() {
        String info;
        try {
            while (true)
            {
                info = dataInputStream.readUTF();
                System.out.println("服务器说:"+info);
                if (info.equals("bye")){
                    System.out.println("对方不想理你了");
                    System.exit(0);
                }

            }
        } catch (IOException e) {
            System.out.println("服务器死翘翘了");
            e.printStackTrace();
        }

    }
}

class MyClientWriter extends Thread {
    private  DataOutputStream dataOutputStream;


    public MyClientWriter(DataOutputStream dataOutputStream) {
        this.dataOutputStream = dataOutputStream;
    }

    @Override
    public void run() {
        InputStreamReader inputStreamReader = new InputStreamReader(System.in);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String info;
        try {
            while (true)
            {
                info = bufferedReader.readLine();
                dataOutputStream.writeUTF(info);
                if (info.equals("bye"))
                {
                    System.out.println("感谢使用");
                    System.exit(0);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
public class TestServer {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket socket = serverSocket.accept();

            OutputStream outputStream = socket.getOutputStream();
            DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

            InputStream inputStream = socket.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(inputStream);

            new MyClientReader(dataInputStream).start();
            new MyServerWriter(dataOutputStream).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class MyServerReader extends  Thread{
    private DataInputStream dataInputStream;


    public MyServerReader(DataInputStream dataInputStream) {
        this.dataInputStream = dataInputStream;
    }

    @Override
    public void run() {
        String info;
        try {
            while (true)
            {
                info = dataInputStream.readUTF();
                System.out.println("客户端说"+info);
                if (info.equals("bye")){
                    System.out.println("对方不想理你了");
                    System.exit(0);
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

class MyServerWriter extends Thread {
    private  DataOutputStream dataOutputStream;


    public MyServerWriter(DataOutputStream dataOutputStream) {
        this.dataOutputStream = dataOutputStream;
    }

    @Override
    public void run() {
        InputStreamReader inputStreamReader = new InputStreamReader(System.in);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String info;
        try {
            while (true)
            {
                info = bufferedReader.readLine();
                dataOutputStream.writeUTF(info);
                if (info.equals("bye"))
                {
                    System.out.println("感谢使用");
                    System.exit(0);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

总结

  1. 其实一位套接字是很难的东西,学下来,感觉还是很容易理解的;
  2. 加油努力吧!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值