java之网络

Posted scanner小霸王

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java之网络相关的知识,希望对你有一定的参考价值。

网络通信

网络:

ip地址(唯一标识主机):

ipv4:4个字节(32位)表示;一个字节的范围是0~255,
(0255).(0255).(0255).(0255)
ip地址的组成:网络地址+主机地址;比如:192.168.16.69;其中192.168.16是网络地址,69是主机地址;
ipv6使用128位表示地址,16个字节,是ipv6的四倍(.......

ipv4的分类:

在开发中0~1024端口尽量不用

域名和端口(监听一个服务才需要端口):

网络通信协议:

网络通信理解:

tcp/ip协议:

用户发送数据时候要打包,用户结束接收数据的时候要拆包

TCP和UDP

InetAddress类


Socket类

(可以当做数据通道两端的插头)

Socket的理解:
Socket通讯完成是需要关闭的,英文Socket的连接的数量是有限的


逻辑分析:

代码实现:
字节传输实例一:

ServerSocket可以创建多个Socket
客户端

public class TcpClient 
    public static void main(String[] args) throws UnknownHostException, IOException 
        //1.连接服务器(ip,端口)
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        //2连接上后,生成SOcket,通过socket.getOutputStream得到输出流
        OutputStream outputStream = socket.getOutputStream();

        //3往输出流写入数据
        outputStream.write("hello".getBytes());
        //4.设置写入结束(否则将陷入阻塞)
        socket.shutdownOutput();

        //5.接受服务端的输入流
        InputStream inputStream = socket.getInputStream();
        byte[] buff = new byte[1024];
        int len;
        while ((len=inputStream.read(buff))!=-1)
            System.out.println("tcpClient读取:"+new String(buff,0,len));
        

        //6.关闭
        inputStream.close();
        outputStream.close();
        socket.close();
        System.out.println("客户端退出--");
    


服务端:

package file;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServer 
    public static void main(String[] args) throws IOException
        //1监听9999端口
        ServerSocket serverSocket = new ServerSocket(9999);
        //2等待连接,连接
        //如果有客户端连接,将返回Socket对象
        Socket socket = serverSocket.accept();
        System.out.print("socket:"+socket.getClass());
        //3.通过socket.getInputStream()读取客户端的数据
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int len =0;
        //4.Io读取
        while((len = inputStream.read(bytes))!=-1)
            System.out.print("serverSocket读取 "+new String(bytes,0,len));
        
        //5.写出一句话
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("serverSocket写出".getBytes());
        //6.设置写入结束
        socket.shutdownOutput();


        //5.关闭流和Io
        outputStream.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
    



字符传输:
也可以writer.newLine()作为接受标记,但是读数据就需要采用readLine()

客户端:

public class TcpClient 
    public static void main(String[] args) throws UnknownHostException, IOException 
        //1.连接服务器(ip,端口)
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        //2连接上后,生成SOcket,通过socket.getOutputStream得到输出流
        OutputStream outputStream = socket.getOutputStream();

        //3往输出流写入数据
        outputStream.write("hello".getBytes());
        //4.设置写入结束(否则将陷入阻塞)
        socket.shutdownOutput();

        //5.接受服务端的输入流
        InputStream inputStream = socket.getInputStream();

        /*byte[] buff = new byte[1024];
        int len;
        while ((len=inputStream.read(buff))!=-1)
            System.out.println("tcpClient读取:"+new String(buff,0,len));
        */
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        char [] chars =new char[100];
        int len;

        while ((len=bufferedReader.read(chars))!=-1)
            System.out.println("tcpClient读取:"+new String(chars,0,len));
        

        bufferedReader.close();

        //6.关闭
        inputStream.close();
        outputStream.close();
        socket.close();
        System.out.println("客户端退出--");
    


服务端:

public class TcpServer 
    public static void main(String[] args) throws IOException
        //1监听9999端口
        ServerSocket serverSocket = new ServerSocket(9999);
        //2等待连接,连接
        //如果有客户端连接,将返回Socket对象
        Socket socket = serverSocket.accept();
        System.out.print("socket:"+socket.getClass());
        //3.通过socket.getInputStream()读取客户端的数据
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int len =0;
        //4.Io读取
        while((len = inputStream.read(bytes))!=-1)
            System.out.print("serverSocket读取 "+new String(bytes,0,len));
        
        //5.写出一句话
        OutputStream outputStream = socket.getOutputStream();
        //        outputStream.write("serverSocket写出".getBytes());
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("serverSocket写出");
        //字节流需要手动刷新
        bufferedWriter.flush();
        //6.设置写入结束
        socket.shutdownOutput();



        //5.关闭流和Io
        outputStream.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
    



服务端:

package 网络;

import java.io.BufferedInputStream;

public class TcpServer2 
	public static void main(String[] args) throws IOException
		//1监听9999端口
		ServerSocket serverSocket = new ServerSocket(9999);
		//2等待连接,连接
		//如果有客户端连接,将返回Socket对象
		Socket socket = serverSocket.accept();
		//3.通过socket.getInputStream()读取客户端的数据
		BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
		//4.将客户端的二进制内容转为数组,
		byte[] buff = StreamUtils.streamToByteArray(bufferedInputStream);
		//5.创建保存文件路径的输出流
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("src/12.jpg"));
		bufferedOutputStream.write(buff);
		//6.回复消息给客户端
		BufferedWriter bufferedWriter =new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
		bufferedWriter.write("收到图片");
		bufferedWriter.flush();//把内容刷入数据通道
		socket.shutdownOutput();//设置写入结束标记
		
		//7.关闭流和Io
		bufferedWriter.close();
		bufferedOutputStream.close();
		bufferedInputStream.close();
		socket.close();
		serverSocket.close();
	

	




客户端:

package 网络;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class TcpClient2 
	public static void main(String[] args) throws UnknownHostException, IOException
		//1.连接服务器(ip,端口)
		Socket socket = new Socket(InetAddress.getLocalHost(),9999);

		//2.包装流,读取数据
		BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("E:/照片/12.jpg"));
		 
		//3.将数据转为字节数组
		byte[] bytes =StreamUtils.streamToByteArray(bufferedInputStream);
		//4往输出流写入数据
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
		bufferedOutputStream.write(bytes);
		//5.设置写入数据的结束标记(注意:socket.shutdownOutput();
		//写完之后就应该执行该语句,一开始我误认为可以在文中最后关闭,结果程序阻塞了)
		socket.shutdownOutput();
		//6.接受服务器反馈回来的消息,
		InputStream inputStream = socket.getInputStream();
		//7.将流的内容转为字符串
		String s = StreamUtils.streamToString(inputStream);
		System.out.println("客户端接受到消息:"+s);
		//8.关闭
		System.out.println("客户端退出--");
		socket.close();
		bufferedInputStream.close();
		bufferedOutputStream.close();
		inputStream.close();
		
	



工具类:

package 网络;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class StreamUtils 
	

	/**
	 * 输出流转化为byte[]
	 * @param is
	 * @return
	 * @throws IOException
	 */
	public static byte[] streamToByteArray(InputStream is) throws IOException
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		
		byte[] b = new byte[1024];
		int len;
		while((len = is.read(b))!=-1)
			bos.write(b,0,len);
		
		byte[] array = bos.toByteArray();
		bos.close();
		return array;
		
		
	
	
	public static String streamToString(InputStream is) throws IOException
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is));
		
		StringBuilder stringBuilder = new StringBuilder();
		String line;
		while((line = bufferedReader.readLine())!=null)
			stringBuilder.append(line+"\\r\\n");
		
	
		return stringBuilder.toString();
		
		
	 


netstat指令:

UDP



基本流程:

例子:

发送端A和发送端B各自发送一句,各自回复一句;
(既是发送端口,也是接收端口)
发送端A:

package MyCode.UDP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UDPSendA 
    public static void main(String[] args) throws IOException 
        //1创建DatagramSocket对象,准备再9998端口接收数据
        DatagramSocket datagramSocket = new DatagramSocket(9999);

        //2准备接收数据
        byte[] buff = new byte[1024];
        //InetAddress.getLocalHost()这里是本机自己玩,也可以InetAddress.getByName(ip)
        DatagramPacket datagramPacket = new DatagramPacket(buff, buff.length);
        //3.接收,当有数据包发送到9999就会接收到数据,否则,将会阻塞等待
        datagramSocket.receive(datagramPacket);

        //4.拆包
        int length = datagramPacket.getLength();
        byte[] data = datagramPacket.getData();
        String s = new String(data,0,length);
        System.out.println("A端收到消息:"+s);

        //5.回复消息给B
        //将需要发送的数据,封装到DatagramPacket对象
        byte[] data2 = "我是A端,我收到消息了".getBytes();
        //InetAddress.getLocalHost()这里是本机自己玩,也可以InetAddress.getByName(ip)
        datagramPacket = new DatagramPacket(data2, data2.length, InetAddress.getLocalHost(), 9998);

        datagramSocket.send(datagramPacket);

        //关闭
        datagramSocket.close();

        System.out.println("A端退出");



    


接收端:

package MyCode.UDP;

import java.io.IOException;
import java.net.*;

public class UDPSendB 
    public static void main(String[] args) throws IOException 
        //1创建DatagramSocket对象,准备再9998端口接收数据
        DatagramSocket datagramSocket = new DatagramSocket(9998);

        //2将需要发送的数据,封装到DatagramPacket对象
        byte[] data = "hello 你好,我是B端".getBytes();
        //InetAddress.getLocalHost()这里是本机自己玩,也可以InetAddress.getByName(ip)
        DatagramPacket datagramPacket = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), 9999);

        datagramSocket.send(datagramPacket);

        //3准备接收数据
        byte[] buff = new byte[1024];
        //InetAddress.getLocalHost()这里是本机自己玩,也可以InetAddress.getByName(ip)
        datagramPacket = new DatagramPacket(buff, buff.length);
        //4.接收,当有数据包发送到9999就会接收到数据,否则,将会阻塞等待
        datagramSocket.receive(datagramPacket);
        //5.拆包
        int length = datagramPacket.getLength();
        data = datagramPacket.getData();
        String s = new String(data,0,length);
        System.out.println("B端收到消息:"+s);

        //关闭
        datagramSocket.close();

        System.out.println("B端退出");



    


以上是关于java之网络的主要内容,如果未能解决你的问题,请参考以下文章

基于TCP协议的网络通信

基于TCP协议网络编程

《图解HTTP》-读数笔记

TCP通信程序

9月23日 学堂在线电路原理练习题

第四次Java实训