网络编程

网络编程

网络通信三要素:IP, 端口 , 协议: UDP TCP

端口:逻辑端口 他的范围 0–65535 其中0-1023被系统所占用,你要用的时候,就不要用别人用过的。

针对IP Java提供了一个类用来描述
tatic InetAddress getByName (String host):在给定主机名的情况下确定主机的 IP 地址。
hostname 这个命令,可以查看主机名

InetAddress inetAddress = InetAddress.getByName("Lenovo-PC");
        //获取IP
        String ip = inetAddress.getHostAddress();
        System.out.println(ip);
        //获取主机名
        String hostName = inetAddress.getHostName();
        System.out.println(hostName);

        System.out.println("============================");

        //传入IP也可以
        InetAddress inetAddress2 = InetAddress.getByName("192.168.31.136");
        String hostAddress = inetAddress2.getHostAddress();	
        String hostName1 = inetAddress2.getHostName();
        System.out.println(hostAddress);
        System.out.println(hostName1);

    }
}

Socket=IP+端端口 也叫做套接字编程。要求通信两端都要有这个Socket,针对不同协议的Socket Java给我们提供了相应的Socket。

UDP协议的特点:通信两端不需要建立连接,发送的数据大小有限制,因为不需要建立连接,效率高一些,但是属于不可靠协议,有肯会发生数据丢失问题。

UDP协议的Socket: DatagramSocket 此类表示用来发送和接收数据报包的套接字。UDP协议的Socket 客户端和服务端用的都是一个类DatagramSocket。

public class fasong {
    public static void main (String[] args) throws IOException {
        DatagramSocket datagramSocket = new DatagramSocket ();
        byte[] bytes = "发送".getBytes ();
        类 DatagramPacket 此类表示数据报包。
     /*   DatagramPacket( byte[] buf, int length, InetAddress address,int port)
        构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。*/
       //数据报包里面封装:你要发送的数据,数据的长度,对方的IP 对方的端口
        DatagramPacket packet = new DatagramPacket (bytes,bytes.length, InetAddress.getByName ("192.168.31.136"),8888);
        datagramSocket.send (packet);//发送数据报包
        datagramSocket.close ();//关闭资源
    }
}
public class jieshou {
    public static void main (String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket (8888);//暴露端口号
        byte[] bytes = new byte[1024];
        DatagramPacket datagramPacket = new DatagramPacket (bytes, bytes.length);

        socket.receive (datagramPacket); //接收发送的数据,他需要一个空的数据报包,用来装发过来的数据
        byte[] data = datagramPacket.getData ();//获取数据包里面的数据
        int length = datagramPacket.getLength ();//获取数据的长度

        int port = datagramPacket.getPort ();//取对方端口
      
        String s = new String (data, 0, length);//转换成字符串
        InetAddress address = datagramPacket.getAddress ();//获取对方IP地址
        String hostAddress = address.getHostAddress ();//对方IP地址
        System.out.println ("IP:"+hostAddress+"端口:"+port+"发送的消息:"+s);
        socket.close ();
    }
}

DatagramSocket( int port)
创建数据报套接字并将其绑定到本地主机上的指定端口。

DatagramPacket( byte[] buf, int length)
构造 DatagramPacket,用来接收长度为 length 的数据包

用线程来做的话:

public class A extends Thread{
    @Override
    public void run () {
        try {
            DatagramSocket datagramSocket = new DatagramSocket ();
            BufferedReader reader = new BufferedReader (new InputStreamReader (System.in));
            while (true){
                System.out.println ("请输入");
                String s = reader.readLine ();
                byte[] bytes = s.getBytes ();
                int length = bytes.length;
                DatagramPacket packet = new DatagramPacket (bytes,length, InetAddress.getByName ("192.168.31.136"),3848);
                datagramSocket.send (packet);
                if( "溜了".equals (s)){
                    break;

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

}

public class B extends Thread{
    @Override
    public void run () {
        try {
            DatagramSocket datagramSocket = new DatagramSocket (3848);
            byte[] bytes = new byte[1024];
            DatagramPacket datagramPacket = new DatagramPacket (bytes,bytes.length);
            System.out.println ("信息传入中");
            while (true){
                datagramSocket.receive (datagramPacket);
                int length = datagramPacket.getLength ();
                String hostAddress = datagramPacket.getAddress ().getHostAddress ();
                int port = datagramPacket.getPort ();
                String s = new String (bytes, 0, length);
                System.out.println ("IP:"+hostAddress+"端口:"+port+"信息:"+s);
                if("溜了".equals (s)){
                    break;
                }
            }
            datagramSocket.close ();
        } catch (IOException e) {
            e.printStackTrace ();
        }
    }
}

A与B之间相互传输信息:

public class A {
    public static void main (String[] args) throws Exception {
        new Thread (new Runnable () {
            @Override
            public void run () {
                try {
                    DatagramSocket datagramSocket = new DatagramSocket (1234);
                    byte[] bytes = new byte[1024];
                    DatagramPacket datagramPacket = new DatagramPacket (bytes, bytes.length);
                    System.out.println ("A平台准备就绪,B平台信号传入中。。。");
                    while (true){
                        datagramSocket.receive (datagramPacket);
                        byte[] data = datagramPacket.getData ();
                        int length = datagramPacket.getLength ();
                        String s = new String (bytes, 0, length);
                        int port = datagramPacket.getPort ();
                        String hostAddress = datagramPacket.getAddress ().getHostAddress ();
                        System.out.println ("IP:"+hostAddress+"端口:"+port+"信息:"+s);

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

        }).start();
//以上是接受B的信息
        sendfasong();

}
    private static void sendfasong() throws Exception{

        DatagramSocket datagramSocket = new DatagramSocket();

        BufferedReader reader = new BufferedReader (new InputStreamReader (System.in));
        while (true) {
            System.out.println("请输入你要发送给B的消息");
            String msg = reader.readLine();
            
            if ("886".equals(msg)) {
                break;
            }
            byte[] bytes = msg.getBytes();
            int length = bytes.length;
           
            DatagramPacket datagramPacket = new DatagramPacket(bytes, length, InetAddress.getByName("192.168.31.136"), 8888);
            datagramSocket.send(datagramPacket);

        }

        //释放资源
        datagramSocket.close();


    }
}
//这段为发送到B的信息块
public class B {
    public static void main (String[] args) throws Exception {
        new Thread (new Runnable () {
            @Override
            public void run () {
                try {
                    DatagramSocket datagramSocket = new DatagramSocket (8888);
                    byte[] bytes = new byte[1024];
                    DatagramPacket datagramPacket = new DatagramPacket (bytes, bytes.length);
                    System.out.println ("A平台准备就绪,B平台信号传入中。。。");
                    while (true){
                        datagramSocket.receive (datagramPacket);
                        byte[] data = datagramPacket.getData ();
                        int length = datagramPacket.getLength ();
                        String s = new String (bytes, 0, length);
                        int port = datagramPacket.getPort ();
                        String hostAddress = datagramPacket.getAddress ().getHostAddress ();
                        System.out.println ("IP:"+hostAddress+"端口:"+port+"信息:"+s);

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

        }).start();

        sendfasong();

    }
    private static void sendfasong() throws Exception{

        DatagramSocket datagramSocket = new DatagramSocket();

        BufferedReader reader = new BufferedReader (new InputStreamReader (System.in));
        while (true) {
            System.out.println("请输入你要发送给B的消息");
            String msg = reader.readLine();
            
            if ("886".equals(msg)) {
                break;
            }
            byte[] bytes = msg.getBytes();
            int length = bytes.length;
       
            DatagramPacket datagramPacket = new DatagramPacket(bytes, length, InetAddress.getByName("192.168.31.136"), 1234);
            datagramSocket.send(datagramPacket);

        }

      
        datagramSocket.close();


    }
}

TCP:通信两段需要建立连接,形成数据传输的通道,属于可靠协议,传输大小无限制。

TCP的客户端套接字:Socket。套接字是两个机器之间的通信的端点。

Socket(InetAddress address, int port)
创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
Socket(String host, int port)

创建一个流套接字并将其连接到指定主机上的指定端口号

public class fasong {
    public static void main (String[] args) throws IOException {
        Socket socket = new Socket ("192.168.31.136",8848);/指定IP与端口
        OutputStream outputStream = socket.getOutputStream ();//获取通信道的输出流
        outputStream.write ("指令发送".getBytes ());
        socket.close ();
    }
}
public class jieshou {
    public static void main (String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket (8848);
        Socket accept = serverSocket.accept ();// //阻塞式方法,侦听客户端的连接
        InputStream inputStream = accept.getInputStream ();//获取数据
        byte[] bytes = new byte[1024];
        int read = inputStream.read (bytes);
        String s = new String (bytes,0,read);//转换成字符串
        String hostAddress = serverSocket.getInetAddress ().getHostAddress ();
        System.out.println ("ip:"+hostAddress+"信息:"+s);
serverSocket.close ();

    }
}

ServerSocket 此类实现服务器套接字。
ServerSocket( int port)
创建绑定到特定端口的服务器套接字。并暴露端口号

//java.net.BindException:Address already in use:JVM_Bind 端口被占用的异常
//java.net.BindException:Address already in use:JVM_Bind 端口被占用的异常

案例:
客户端发送数据,服务器接受数据并给出反馈

public class fasong {
    public static void main (String[] args) throws IOException {
        Socket socket = new Socket ("192.168.31.136",8848);
        OutputStream outputStream = socket.getOutputStream ();
        outputStream.write ("指令发送".getBytes ());
        InputStream inputStream = socket.getInputStream ();
        byte[] bytes = new byte[1024];
        int read = inputStream.read (bytes);
        String s = new String (bytes,0,read);
        System.out.println (s);

        socket.close ();
    }
}
public class jieshou {
    public static void main (String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket (8848);
        Socket accept = serverSocket.accept ();
        InputStream inputStream = accept.getInputStream ();
        byte[] bytes = new byte[1024];
        int read = inputStream.read (bytes);
        String s = new String (bytes,0,read);
        OutputStream outputStream = accept.getOutputStream ();
        outputStream.write ("请求接受".getBytes ());
        String hostAddress = serverSocket.getInetAddress ().getHostAddress ();
        System.out.println ("ip:"+hostAddress+"信息:"+s);
serverSocket.close ();

    }
}

案例:
客户端键盘录入服务器控制台输出

public class kehuduan {
    public static void main (String[] args) throws IOException {
        Socket socket = new Socket ("192.168.31.136",8848);
        OutputStream outputStream = socket.getOutputStream ();
        BufferedReader reader = new BufferedReader (new InputStreamReader (System.in));

        BufferedWriter writer = new BufferedWriter (new OutputStreamWriter (outputStream));
        while (true){
            System.out.println ("请输入");
            String s = reader.readLine ();
            if ("溜了".equals (s)){
                break;
            }
            writer.write (s);
            writer.newLine ();
            writer.flush ();
        }
        outputStream.close ();
    }
}
public class server {
    public static void main (String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket (8848);
        Socket accept = serverSocket.accept ();
        InputStream inputStream = accept.getInputStream ();
        BufferedReader reader = new BufferedReader (new InputStreamReader (inputStream));
        BufferedWriter writer = new BufferedWriter (new FileWriter ("123.txt"));
        String s=null;
        while ((s=reader.readLine ())!=null){
            System.out.println (s);
           
        }

    }
}

案例:
客户端读取文本文件服务器控制台输出

public class MyClient {
    public static void main(String[] args) throws IOException {

       
        Socket socket = new Socket("192.168.31.136", 9999);
        OutputStream out = socket.getOutputStream();
        //你可以把通道中的字节流,包装成字符流
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
        //创建输入流来读取文本文件
        BufferedReader reader = new BufferedReader(new FileReader("LHC.java"));
        String line=null;
        while ((line=reader.readLine())!=null){
            writer.write(line);
            writer.newLine();
            writer.flush();
        }
      
        socket.close();
        reader.close();

    }
}

public class MyServer {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(9999);
        System.out.println("服务端已经开启,等待连接。。。。。");
        Socket sk = ss.accept();
        InputStream in = sk.getInputStream();
        //把通道中的字节流,包装成字符流
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String s =null;
        while ((s=reader.readLine())!=null){
            System.out.println(s);
        }
      
    }
}

TCP协议上传文本文件

public class TCPClient {
    public static void main(String[] args) throws IOException {
       
        Socket socket = new Socket("192.168.31.136", 5555);
        //获取通道中的输入流,输出流
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();

        BufferedReader reader= new BufferedReader(new FileReader("LHC.java"));
        String line=null;
        //包装通道中的输出流
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
        while ((line=reader.readLine())!=null){
            writer.write(line);
            writer.newLine();
            writer.flush();
        }

        //释放资源
        socket.close();
        reader.close();

    }
}
public class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(5555);
        System.out.println("服务器已经开启等待连接。。。。。");
        Socket socket = serverSocket.accept();
        //获取通道中的输入输出流
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();
        //包装通道中的输入流
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        BufferedWriter writer = new BufferedWriter(new FileWriter("xiazai.java"));
        String line=null;
        while ((line=reader.readLine())!=null){
            writer.write(line);
            writer.newLine();
            writer.flush();
        }

        serverSocket.close();
        writer.close();
    }
}

TCP上传文本文件并给出反馈

public class TCPClient {
    public static void main(String[] args) throws IOException {
      
        Socket socket = new Socket("192.168.31.136", 5555);
        //获取通道中的输入流,输出流
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();

        BufferedReader reader= new BufferedReader(new FileReader("TCPClient.java"));
        String line=null;
        //包装通道中的输出流
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
        while ((line=reader.readLine())!=null){
            writer.write(line);
            writer.newLine();
            writer.flush();
        }
        
        writer.write("over");
        writer.newLine();
        writer.flush();

        //读取服务端的反馈
        byte[] bytes = new byte[1024];
        int len = in.read(bytes); //读取服务端的反馈,读取不到,就阻塞在这里
        System.out.println(new String(bytes,0,len));

        //释放资源
        socket.close();
        reader.close();

    }
}

public class TCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(5555);
        System.out.println("服务器已经开启等待连接。。。。。");
        Socket socket = serverSocket.accept();
        //获取通道中的输入输出流
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();
        //包装通道中的输入流
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        BufferedWriter writer = new BufferedWriter(new FileWriter("upload2.java"));
        String line=null;
        while ((line=reader.readLine())!=null){
            //如果读取到客户端写过来的一个标记,我就结束这个循环。
            if ("over".equals(line)) {
                break;
            }
            writer.write(line);
            writer.newLine();
            writer.flush();
        }

        //如果上传成功,服务端给客户端一个反馈
        out.write("上传服务器成功".getBytes());
        System.out.println("服务端下来了");
        serverSocket.close();
        writer.close();
    }
}

但是此处的“over”自定义结束符存在:如果文本中途出现“over”,那么势必会导致文本传出不全。

public class TCPClient {
    public static void main(String[] args) throws IOException {



        //上传文本文件
        Socket socket = new Socket("192.168.47.1", 5555);
        //获取通道中的输入流,输出流
        InputStream in = socket.getInputStream();
        OutputStream out = socket.getOutputStream();

        BufferedReader reader= new BufferedReader(new FileReader("TCPClient.java"));
        String line=null;
        //包装通道中的输出流
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
        while ((line=reader.readLine())!=null){
            writer.write(line);
            writer.newLine();
            writer.flush();
        }
          //可以用另一个方案,可户端传完之后,把通道中的是输出流关掉,服务端那边就不会在等待了。

        socket.shutdownOutput();


        //读取服务端的反馈
        byte[] bytes = new byte[1024];
        int len = in.read(bytes); //读取服务端的反馈,读取不到,就阻塞在这里
        System.out.println(new String(bytes,0,len));

        //释放资源
        socket.close();
        reader.close();

    }
}

多线程改进上传文本文件

public class TCPServer {
    public static void main(String[] args) throws IOException {
        //让一个服务端。连接多个客户端。
        ServerSocket serverSocket = new ServerSocket(5555);
        System.out.println("服务器已经开启等待连接。。。。。");
        int i=1;
        while (true){
            //循环侦听客户端
            Socket socket = serverSocket.accept();
            System.out.println((i++)+"个客户端连接上来了");
            //为每一个连接上来的客户端,单独开启一个线程来处理
            //把每个客户端socket 传入到线程里面去
            new UpLoadThread(socket).start();
        }
    }
}

你可能感兴趣的:(java)