天天看点

0070 TCP网络通信编程

0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
0070 TCP网络通信编程
import java.net.InetAddress;
import java.net.UnknownHostException;

/*
    网络:两台或多台设备通过一定物理设备连接起来构成了网络
    根据网络覆盖范围不同,可分为:
    局域网:覆盖范围最小,仅仅覆盖一个教室或一个机房
    域域网:覆盖范围较大,可以覆盖一个城市
    广域网:覆盖范围最大,可以覆盖全国甚至全球,如万维网

    IP地址:用于唯一标识网络中的每台计算机
    查看IP地址:ipconfig
    IP地址的表示形式:点分十进制 xx.xx.xx.xx  ,每个十进制的范围:0--255
    对于IPV4 4个字节(32位)表示,一个字节的范围0--255
    IP地址的组成:网络地址+主机地址 如192.168.1.106
    IPV6是互联网工程任务设计的用于替代IPV4的下一代IP协议,IPV6使用128位表示地址,是IPV4的4倍,点分十进制不再适用
    用冒分十六进制,0位压缩,内嵌IPV4地址等方法表示

    域名:将IP地址映射成域名,如www.csdn.net
    端口号:用于标识计算机上某个特定的网络程序
    表示形式:以整数形式,范围0~65535,0~1024已被占用
    常见网络程序端口:
    tomcat 8080,mysql 3306,oracle 1521,sqlserver 1433

    协议
    TCP/IP,中文译名为传输控制协议/因特网互联协议,是Internet最基本的协议

    网络通信协议
    OSI模型               TCP/IP模型                TCP/IP模型各层对应协议
    应用层                 应用层                     HTTP,ftp,teInet,DNS..
    表示层                 应用层
    会话层                 应用层

    传输层                 传输层(TCP)               TCP,UDP,....
    网络层                 网络层(IP)                 IP,ICMP,ARP.....

    数据链路层             物理+数据链路层              Link
    物理层                 物理+数据链路层

    TCP协议
    1.使用协议前,需建立TCP连接,形成传输数据通道
    2.传输前,采用"三次握手"方式,是可靠的
    3.TCP协议进行通信的两个应用进程:客户端、服务端
    4.在连接中可进行大数据量传输
    5.传输完毕需释放已建立的连接,效率低

    UDP协议
    1.将数据、源、目的封装成数据包,不需建立连接
    2.每个数据包的大小限制在64K内
    3.无需链接,所以不可靠
    4.发送数据结束时无需释放资源,效率高

    InetAddress类
    相关方法
    getLocalHost            //获取本机InetAddress对象
    getByName               //根据指定主机名/域名获取IP地址对象
    getHostName             //获取InetAddress对象的主机名
    getHostAddress          //通过InetAddress对象获取地址
 */
//  演示InetAddress类的使用
public class network_ {
    public static void main(String[] args) throws UnknownHostException {
        //获取本机InetAddress对象
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);//计算机名+IP地址
        //根据指定主机名/域名获取IP地址对象
        InetAddress host = InetAddress.getByName("huang");
        System.out.println(host);//计算机名+IP地址
        //根据域名返回InetAddress对象,如输入csdn域名
        InetAddress host2 = InetAddress.getByName("www.csdn.net");
        System.out.println(host2);//www.csdn.net/60.205.172.2
        //获取InetAddress对象的主机名
        String hostName = host2.getHostName();
        System.out.println(hostName);//www.csdn.net
        //通过InetAddress对象获取地址
        String hostAddress = host2.getHostAddress();
        System.out.println(hostAddress);//60.205.172.2

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

/*
    Socket
    1.套接字(Socket)开发网络应用程序被广泛应用,成为事实上的标准
    2.通信的两端都要有Socket,是两台机器间通信的端点
    3.网络通信其实就是Socket间的通信
    4.Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输
    5.一般主动发起通信的应用属客户端,等待通信请求的为服务端
    读写数据
    socket.getOutputStream()
    socket.getInputStream()

    TCP网络通信编程
    1.基于客户端——服务端的网络通信
    2.底层使用的是TCP/IP协议

    设置结束标记
    socket.shutdownOutput();
 */
/*  编写一个服务端和一个客户端,服务器端在9999端口监听
    客户端连接到服务器端,发送hello,server,并接收服务器端回发的hello,client,之后退出
    服务器端接收到客户端发送的信息,输出并发送hello,client,之后退出
 */
//  服务端(字节流)
@SuppressWarnings({"all"})
public class TCP_Server {
    public static void main(String[] args) throws IOException {
        //1. 在本机 的 9999 端口监听, 等待连接
        //      要求在本机没有其它服务在监听 9999
        //      ServerSocket 可以通过 accept() 返回多个 Socket[多个客户端连接服务器的并发]
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端,在 9999 端口监听,等待连接..");
        //2. 当没有客户端连接 9999 端口时,程序会 阻塞, 等待连接
        // 如果有客户端连接,则会返回 Socket 对象,程序继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端 socket =" + socket.getClass());
        //3. 通过 socket.getInputStream() 读取客户端写入到数据通道的数据, 显示
        InputStream inputStream = socket.getInputStream();
        //4. IO 读取
        byte[] buf = new byte[1024];
        int readLen = 0;
        while ((readLen = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLen));//根据读取到的实际长度,显示内容
        }
            //5. 获取 socket 相关联的输出流
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write("hello, client".getBytes());
            // 设置结束标记
            socket.shutdownOutput();
            //6.关闭流和 socket
            outputStream.close();
            inputStream.close();
            socket.close();
            serverSocket.close();//关闭
    }
}
      
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
//  客户端(字节流)
@SuppressWarnings({"all"})
public class TCP_Client {
    public static void main(String[] args) throws IOException {
        //1. 连接服务端 (ip , 端口)
        //   连接本机的 9999 端口, 如果连接成功,返回 Socket 对象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客户端 socket 返回=" + socket.getClass());
        //2. 连接上后,生成 Socket, 通过 socket.getOutputStream()
        // 得到 和 socket 对象关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //3. 通过输出流,写入数据到 数据通道
        outputStream.write("hello, server".getBytes());
        // 设置结束标记
        socket.shutdownOutput();
        //4. 获取和 socket 关联的输入流. 读取数据(字节),并显示
        InputStream inputStream = socket.getInputStream();
        byte[] buf = new byte[1024];
        int readLen = 0;
        while ((readLen = inputStream.read(buf)) != -1) {
            System.out.println(new String(buf, 0, readLen));
        }
        //5. 关闭流对象和 socket, 必须关闭
        inputStream.close();
        outputStream.close();
        socket.close();
        System.out.println("客户端退出.....");
    }
}      
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

//  服务端(字符流)
@SuppressWarnings({"all"})
public class TCP_Server02 {
    public static void main(String[] args) throws IOException {
        //1. 在本机 的 9999 端口监听, 等待连接
        //      要求在本机没有其它服务在监听 9999
        //      ServerSocket 可以通过 accept() 返回多个 Socket[多个客户端连接服务器的并发]
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端,在 9999 端口监听,等待连接..");
        //2. 当没有客户端连接 9999 端口时,程序会 阻塞, 等待连接
        // 如果有客户端连接,则会返回 Socket 对象,程序继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端 socket =" + socket.getClass());
        //3. 通过 socket.getInputStream() 读取客户端写入到数据通道的数据, 显示
        InputStream inputStream = socket.getInputStream();
        //4. IO 读取
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);
        //5. 获取 socket 相关联的输出流
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello,client");
        bufferedWriter.newLine();//插入换行符,表示内容结束
        bufferedWriter.flush();//使用字符流,需要手动刷新,否则数据不会写入数据通道
        // 设置结束标记
        socket.shutdownOutput();
        //6.关闭流和 socket
        bufferedReader.close();
        bufferedWriter.close();
        socket.close();
        serverSocket.close();//关闭
    }
}      
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

//  客户端(字节流)
@SuppressWarnings({"all"})
public class TCP_Client02 {
    public static void main(String[] args) throws IOException {
        //1. 连接服务端 (ip , 端口)
        //   连接本机的 9999 端口, 如果连接成功,返回 Socket 对象
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客户端 socket 返回=" + socket.getClass());
        //2. 连接上后,生成 Socket, 通过 socket.getOutputStream()
        // 得到 和 socket 对象关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //3. 通过输出流,写入数据到 数据通道
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello,server");
        bufferedWriter.newLine();//插入换行符,表示写入内容结束,即结束标记,要求对方使用readLine()
        bufferedWriter.flush();//使用字符流,需要手动刷新,否则数据不会写入数据通道

        //4. 获取和 socket 关联的输入流. 读取数据(字节),并显示
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);
        //5. 关闭流对象和 socket, 必须关闭
        bufferedWriter.close();//关闭外层流
        bufferedReader.close();
        socket.close();
        System.out.println("客户端退出.....");
    }
}
      
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

//  服务端(字符流)
@SuppressWarnings({"all"})
public class TCP_Server02 {
    public static void main(String[] args) throws IOException {
        //1. 在本机 的 9999 端口监听, 等待连接
        //      要求在本机没有其它服务在监听 9999
        //      ServerSocket 可以通过 accept() 返回多个 Socket[多个客户端连接服务器的并发]
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端,在 9999 端口监听,等待连接..");
        //2. 当没有客户端连接 9999 端口时,程序会 阻塞, 等待连接
        // 如果有客户端连接,则会返回 Socket 对象,程序继续
        Socket socket = serverSocket.accept();
        System.out.println("服务端 socket =" + socket.getClass());
        //3. 通过 socket.getInputStream() 读取客户端写入到数据通道的数据, 显示
        InputStream inputStream = socket.getInputStream();
        //4. IO 读取
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);
        //5. 获取 socket 相关联的输出流
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello,client");
        bufferedWriter.newLine();//插入换行符,表示内容结束
        bufferedWriter.flush();//使用字符流,需要手动刷新,否则数据不会写入数据通道
        // 设置结束标记
        socket.shutdownOutput();
        //6.关闭流和 socket
        bufferedReader.close();
        bufferedWriter.close();
        socket.close();
        serverSocket.close();//关闭
    }
}
      
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

//  客户端
public class TCP_Client03 {
    public static void main(String[] args) throws Exception {
        //客户端连接服务端
        Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
        //创建读取磁盘文件的输入流
        String filePath = "d:\\demo.png";
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filePath));
        //bytes就是filePath对应的字节数组
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        //通过socket获取到输出流,将bytes发送给服务端
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        //将文件对应的字节数组写入对应的数据通道
        bos.write(bytes);
        bis.close();
        //设置写入数据的结束标记
        socket.shutdownOutput();

        //接收服务端回复的消息
        InputStream inputStream = socket.getInputStream();
        //使用Utils方法将inputStream转成字符串
        String s = StreamUtils.streamToString(inputStream);
        System.out.println(s);
        //关流
        inputStream.close();
        bos.close();
        socket.close();

    }
}      
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
//此类用于演示关于流的读写方法

public class StreamUtils {
    //  将输入流转换成byte[]
    public static byte[] streamToByteArray(InputStream is) throws Exception{
        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;
    }
    //  将InputStream转换成String
    public static String streamToString(InputStream is) throws Exception{
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder builder= new StringBuilder();
        String line;
        while((line=reader.readLine())!=null){ //当读取到 null时,就表示结束
            builder.append(line+"\r\n");
        }
        return builder.toString();
    }
}      
/*
    netstat指令
    netstat-an 查看当前主机网络情况,包括端口监听和网络连接情况
    netstat-an|more 分页显示
    要求在dos控制台下执行

    Listening 表示某个端口在监听
    如果有一个外部程序(客户端)连接到该端口,就会显示一条连接信息
    可以输入ctrl+c退出指令

    当客户端连接到服务端后,实际上客户端也是通过一个端口和服务端进行通讯的,这个端口是TCP/IP来分配的,是不确定的,随机的
 */