• Java网络


      计算机网络中实现通信不需要有一些约定即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等指定标准。为了使两个结点之间能进行对话,必须在他们之间建立通信工具(即接口),使彼此之间能进行信息交换。
      接口包括两部分:
        1.硬件装置:实现节点之间的信息传送。
        2.软件装置:规定双方进行通信的约定协议。

    为什么要分层:
      由于节点之间的联系很复杂,在制订协议时,把复杂的成分分解成一些简单的成分,再将他们复合起来。最常用的的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展。
    通信协议的分层规定:
      把用户应用程序作为最高层,把物理通信线路作为最底层,将其间的协议处理分为若干层,规定每层处理的任务,也规定每层的接口标准。

    OSI参考模型:
      应用层---->表示层---->会话层---->传输层---->网络层---->数据链路层---->物理层
    TCP/IP参考模型:
      应用层---->传输层---->网络层---->物理+数据链路层

    IP协议是网际层的主要协议,支持网间互联的数据报通信。它提供的主要功能有:
      1.无连接数据报传送
      2.数据报路由选择和差错控制


    Socket:
      两个Java应用程序可通过一个双向的网络通信连接实现数据交换,这个双向链路的一段称为一个Socket。Socket通常用来实现client-server连接。java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连接的client和server端。建立连接时所需的寻址信息为远程计算机的IP地址和端口号(port number)。TCP、UDP的端口是分开的,各有65536个。

    TCP(传输控制协议):

      是专门设计用于在不可靠的因特网上提供可靠的、端到端的字节流通信协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。

    例子1:

    import java.net.*;
    import java.io.*;
    
    public class TCPServer {
        public static void main(String[] args) throws Exception {
            ServerSocket ss = new ServerSocket(6666);
            while(true) {
                Socket s = ss.accept();
    System.out.println("a client connect!");
                DataInputStream dis = new DataInputStream(s.getInputStream());
                System.out.println(dis.readUTF());
                dis.close();
                s.close();
            }
            
        }
    }
    
    import java.net.*;
    import java.io.*;
    
    public class TCPClient {
        public static void main(String[] args) throws Exception {
            Socket s = new Socket("127.0.0.1", 6666);
            OutputStream os = s.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            Thread.sleep(30000);
            dos.writeUTF("hello server!");
            dos.flush();
            dos.close();
            s.close();
        }
    }

    例子2:

    import java.io.*;
    import java.net.*;
    public class talkclient
    {
        public static void main(String args[])
        {
            try
            {
                Socket socket = new Socket("127.0.0.1",4700);
                BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));    //从键盘中读取
                PrintWriter os = new PrintWriter(socket.getOutputStream());    //输出到服务器端
                BufferedReader is = new BufferedReader(new InputStreamReader(    //从服务器端读取
                    socket.getInputStream()));
                String readline;
                readline = sin.readLine();
                while (!readline.equals("bye"))    
                {
                    os.println(readline);
                    os.flush();
                    System.out.println("Client:" + readline);
                    System.out.println("Server:" + is.readLine());
                    readline = sin.readLine();
                }
                os.close();
                is.close();
                socket.close();
            }catch(Exception e)
            {
                System.out.println("Error" + e);
            }
        }
    }
                
    
    import java.io.*;
    import java.net.*;
    public class talkserver
    {
        public static void main(String args[])
        {
            try
            {
                ServerSocket server = null;
                try
                {
                    server = new ServerSocket(4700);
                }catch(Exception e)
                {
                    System.out.println("can not listen to:" + e);
                }
                Socket socket = null;
                try
                {
                    socket = server.accept();
                }catch(Exception e)
                {
                    System.out.println("Error:" + e);
                }
                String line;
                BufferedReader is = new BufferedReader(new InputStreamReader(    //从客户端读取
                    socket.getInputStream()));
                PrintWriter os = new PrintWriter(socket.getOutputStream());    //输出到客户端
                BufferedReader sin = new BufferedReader(new InputStreamReader(System.in));    //从键盘中读取
                System.out.println("Client:" + is.readLine());
                line = sin.readLine();
                while (!line.equals("bye"))    
                {
                    os.println(line);
                    os.flush();
                    System.out.println("Server:" + line);
                    System.out.println("Client:" + is.readLine());
                    line = sin.readLine();
                }
    
                is.close();
                os.close();
                socket.close();
                server.close();
            }catch(Exception e)
            {
                System.out.println("Error" + e);
            }
        }
    }

    UDP(用户数据报协议):

      UDP想应用程序提供了一种发送封装的原始IP数据报的方式,并且发送时无需建立连接,是一种不可靠的连接。

    import java.net.*;
    import java.io.*;
    
    public class TestUDPClient
    {
        public static void main(String args[]) throws Exception
        {
            long n = 10000L;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();    //自动会生成一个字节数组
            DataOutputStream dos = new DataOutputStream(baos);
            dos.writeLong(n);    //通过流向字节数组写入一个Long类型的数
            
            byte[] buf = baos.toByteArray();    //得到baos指向的字节数组
    System.out.println(buf.length);
            
            DatagramPacket dp = new DatagramPacket(buf, buf.length,     //利用该字节数组构造一个数据报
                                                   new InetSocketAddress("127.0.0.1", 5678)    //发送的目的地址
                                                   );
            DatagramSocket ds = new DatagramSocket(9999);    //构建一个套接字,监听在9999端口
            ds.send(dp);    //通过此套接字发送数据报
            ds.close();
            
        }
    }
    
    import java.net.*;
    import java.io.*;
    
    public class TestUDPServer
    {
        public static void main(String args[]) throws Exception
        {
            byte buf[] = new byte[1024];
            DatagramPacket dp = new DatagramPacket(buf, buf.length);    //将数据报内容与字节数组关联
            DatagramSocket ds = new DatagramSocket(5678);
            while(true)
            {
                ds.receive(dp);    //通过套接字接收数据报并关联到dp
                ByteArrayInputStream bais = new ByteArrayInputStream(buf);    //读入字节数组的内容
                DataInputStream dis = new DataInputStream(bais);
                System.out.println(dis.readLong());
            }
        }
    }

    要特别注意字节数组的作用。

    错误的用法:

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPserver {
        public static void main(String args[]) throws IOException{
            ServerSocket ss = new ServerSocket(6666);
            Socket s = ss.accept();
            System.out.print("连接成功!");
            InputStreamReader isr = new InputStreamReader(s.getInputStream());
            System.out.print((char)isr.read()); //read一次读一个字符
        isr.close();
        }
    }
    
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.net.Socket;
    
    public class TCPClient {
        public static void main(String args[]) throws IOException{
            Socket s = new Socket("127.0.0.1",6666);
            OutputStreamWriter os = new OutputStreamWriter(s.getOutputStream());
            os.write("wuenqiang");
            //os.close(); //假如我们将关闭语句注释掉,则字符串在缓冲区中,并没有被刷进流中,所以读写的时候会出错
        }
    }

    字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件,关闭时会自动刷出。

  • 相关阅读:
    windows中抓取hash小结(上)
    内网横向移动常见方法
    常见默认服务端口整理
    Kerberos认证流程简述
    SQL注入之MySQL报错注入整理
    域内常用命令整理
    一个极其朴素的目录扫描Python脚本
    5. 7冲刺记录
    5. 6冲刺记录
    梦断代码阅读笔记
  • 原文地址:https://www.cnblogs.com/mosquito-woo/p/3921849.html
Copyright © 2020-2023  润新知