Java 笔记之网络编程入门

网络编程入门

网络编程概述

计算机网络:是将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议管理和协调下,实现资源共享和信息传递的计算机系统。

Java 笔记之网络编程入门_第1张图片

网络编程:在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换。

网络编程的三要素

1.IP地址:要想让网络中的计算机能够相互通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接受数据的计算机和识别发送的计算机,而IP地址就是这个标识号。也就是设备的标识。

2.端口:网络的通信本质上是两个应用程序的通信。每台计算机都有很多应用程序,那么网络在通信时,如何区分这些应用程序呢?如果说IP地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的应用程序,也就是应用程序的标识。

3.协议:通过计算机网络可以使多台计算机实现连接,位于同一网络的计算机在进行连接和通信时需要遵守一定的规则,这些连接和通信规则被称为网络通信协议,他对数据的传输格式、传输速率、传输步骤等做了统一的规定,通信双方必须同时遵守才能完成数据交换。常见的协议有UDP协议和TCP协议。

IP地址:

Java 笔记之网络编程入门_第2张图片

常用命令:

1.ipconfig:查看本机的IP地址

2.ping IP地址:检查网络是否连通

特殊地址:

127.0.0.1 :是回送地址,可以代替本机地址,一般用来测试使用

InetAddress的使用

为了方便我们对IP地址的获取和操作,Java提供了一个类InetAddress供我们使用

InetAddress:此类表示Internet协议(IP)地址

方法名 说明
static InetAddress getByName(String host) 确定主机名称的IP地址。主机名称可以是机器名称也可以是IP地址。
String getHostName() 获取此IP地址的主机名
String getHostAddress() 获取文本显示中的IP地址字符串
package com.it;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.SortedMap;

public class InetAddressDemo {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress address = InetAddress.getByName("192.168.1.7");//这里也可以是主机名

        String name = address.getHostName();
        String ip = address.getHostAddress();

        System.out.println("主机名:"+name);
        System.out.println("IP地址:"+ip);
    }
}

端口

端口:设备上应用程序的唯一标识

协议

协议:计算机网络中,连接和通信的规则被称为网络通信协议

Java 笔记之网络编程入门_第3张图片

Java 笔记之网络编程入门_第4张图片

Java 笔记之网络编程入门_第5张图片

UDP通信程序

UDP通信原理

UDP协议是一种不可靠的网络协议,它在通信两端各建立一个Socket对象,但是这两个Socket只是发送和接收数据的对象,因此对于基于UDP协议的通信双方而言,没有所谓的客户端与服务器的概念

Java提供了DatagramSocket类作为基于UDP协议的Socket

UDP发送数据

步骤:

1.创建发送端的Socket对象(DatagramSocket)

DatagramSocket() //构造数据报套接字并将其绑定到本地主机的任何端口

2.创建数据,并把数据打包

DatagramPacket(byte[] buf,int length,InetAddress address,int port) //构造一个数据报,发送长度为length的数据报到指定主机上的指定端口号

3.调用DatagramSocket对象的方法发送数据

void send(DatagramPacket p) //从此套接字发送数据包

4.关闭发送端

void close() //关闭数据报套接字

UDP接收数据

步骤:

1.创建接收端的Socket对象(DategramSocket)

DatagramSocket(int port)

2.创建一个数据包用于接收数据

DatagramPacket(byte[] buf,int length)

3.调用DatagramSocket对象的方法接收数据

void receive(DatagramPacker dp)

4.解析数据包,并把数据在控制台上显示

byte[] getData()

int getLength()

5.关闭接收端

void close()

//ReceiveDemo.java
package com.itUDP;

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

public class ReceiveDemo1 {
    public static void main(String[] args) throws IOException {
        //创建接收端的Socket对象(DategramSocket)
        DatagramSocket ds = new DatagramSocket(2000);

        //创建一个数据包用于接收数据
        byte[] bys = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bys,bys.length);

        //调用DatagramSocket对象的方法接收数据
        ds.receive(dp);

        //解析数据包,并把数据在控制台上显示
        byte[] data = dp.getData();
        String datas = new String(data);    
        System.out.println("数据是:"+datas);

        //关闭接收端
        ds.close();
    }
}

//SendDemo.java
package com.itUDP;

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

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

        //创建发送端的Socket对象(DatagramSocket)
        DatagramSocket ds = new DatagramSocket();

        //创建数据,并把数据打包
        byte[] bys = "你好,UDP!".getBytes();
        int length  = bys.length;
        InetAddress address = InetAddress.getByName("192.168.1.7");
        int port = 2000;
        DatagramPacket dp = new DatagramPacket(bys,length,address,port);

        //调用DatagramSocket对象的方法发送数据
        ds.send(dp);

        //关闭发送端
        ds.close();
    }
}

UDP 通信程序练习

按照下面要求实现程序:

UDP发送数据:数据来自于键盘输入,直到输入的数据是886,发送数据结束。

UDP接收数据:因为接收端不知道接收数据什么时候停止发送,故采用死循环接收。

//ReceiveDemo.java
package com.itUDP;

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

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

        DatagramSocket  ds = new DatagramSocket(2001);

        while(true){

            byte[] bys = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bys, bys.length);

            ds.receive(dp);

            byte[] data = dp.getData();
            String s = new String(data,0,dp.getLength());
            System.out.println("数据是:"+s);
        }

        //ds.close();
    }
//SendDemo.java
package com.itUDP;

import java.io.*;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

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

        //构造数据报套接字并将其绑定到本地主机的任何端口
        DatagramSocket ds = new DatagramSocket();

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while((line = br.readLine())!=null){
            if("886".equals(line)){
                break;
            }
            byte[] bys = line.getBytes();
            DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("192.168.1.7"),2001);

            ds.send(dp);
        }

        ds.close();
    }
}

}

TCP通信程序

TCP通信原理:

Java 笔记之网络编程入门_第6张图片

TCP发送数据:

步骤:

1.创建客户端的Socket对象(Socket)

Socket(String host,int port)

2.获取输出流,写数据

OutputStream getOutputStream()

3.释放资源

void close()

TCP接收数据

步骤:

1.创建服务器端的Socket对象(ServerSocket)

ServerSocket(int port)

2.监听客户端连接,返回一个Socket对象

Socket accept()

3.获取输入流,读数据,并把数据显示在控制台

InputStream getInputStream()

4.释放资源

void close()

TCP通信程序练习

练习一:

客户端发送数据,接收服务器反馈

服务器接收数据,给出反馈

//ServerDemo.java
package com.itTCP;

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

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

        //创建服务器端的Socket对象(ServerSocket)
        ServerSocket ss = new ServerSocket(10010);

        //侦听要连接的套接字,并接受他
        Socket s = ss.accept();

        //获取输入流,读数据,并把数据显示在控制台
        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];
        int len = is.read(bys);
        String data = new String(bys,0,len);
        System.out.println("服务器:"+data);

        //给出反馈
        OutputStream os = s.getOutputStream();
        os.write("数据已收到!".getBytes());

        //释放资源
        s.close();
        ss.close();
    }
}


//ClientDemo.java
package com.itTCP;

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

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

        //创建客户端的Socket对象(Socket)
        Socket s = new Socket("192.168.1.7",10010);

        //获取输出流,写数据
        OutputStream os =s.getOutputStream();
        os.write("hello,tcp".getBytes());

        //接收服务器的反馈
        byte[] bys = new byte[1024];
        InputStream is = s.getInputStream();
        int len = is.read(bys);
        String str = new String(bys,0,len);
        System.out.println("客户端"+str);

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

    }
}

练习2:

客户端:数据来自键盘的输入,直到输入的数据是886,发送数据结束

服务端:接收的数据在控制台输出

ServerDemo2.java
package com.itTCP;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo2 {
    public static void main(String[] args) throws IOException {
        //接收的数据在控制台输出

        ServerSocket ss = new ServerSocket(10010);

        Socket s = ss.accept();

        BufferedReader br  = new BufferedReader(new InputStreamReader(s.getInputStream()));

        String line;
        while((line=br.readLine())!=null){
            System.out.println(line);
        }

        ss.close();

    }
}


//ClientDemo2.java
package com.itTCP;

import java.io.*;
import java.net.Socket;

public class ClientDemo2 {
    public static void main(String[] args) throws IOException {
        //数据来自键盘的输入,直到输入的数据是886,发送数据结束

        Socket s = new Socket("192.168.1.7",10010);

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while((line= br.readLine())!=null){
            if("886".equals(line)){
                break;
            }
            //获取输出流对象
//            OutputStream os = s.getOutputStream();
//            os.write(line.getBytes());
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

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

    }
}

练习三:

客户端:数据来自键盘的输入,直到输入的数据是886,发送数据结束

服务端:接收到的数据写入文本文件

//ServerDemo3.java
package com.itTCP;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo3 {
    public static void main(String[] args) throws IOException {
        //接收到的数据写入文本文件

        ServerSocket ss  = new ServerSocket(10010);

        Socket s = ss.accept();

        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new FileWriter("F://tcp.txt"));

        String line;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        bw.close();
        ss.close();

    }
}

//ClientDemo.java
package com.itTCP;

import java.io.*;
import java.net.Socket;

public class ClientDemo3 {
    public static void main(String[] args) throws IOException {
        //数据来自键盘的输入,直到输入的数据是886,发送数据结束

        Socket s = new Socket("192.168.1.7",10010);

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        String line;
        while((line= br.readLine())!=null){
            if("886".equals(line)){
                break;
            }
            //获取输出流对象
//            OutputStream os = s.getOutputStream();
//            os.write(line.getBytes());
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

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

    }
}

练习四:

客户端:数据来自文本文件

服务端:接收到的数据写入文本文件

//ServerDemo4.java
package com.itTCP;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo4 {
    public static void main(String[] args) throws IOException {
        //接收到的数据写入文本文件

        ServerSocket ss  = new ServerSocket(10010);

        Socket s = ss.accept();

        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new FileWriter("F://tcpwrite.txt"));

        String line;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        bw.close();
        ss.close();

    }
}

//ClientDemo.java
package com.itTCP;

import java.io.*;
import java.net.Socket;

public class ClientDemo4 {
    public static void main(String[] args) throws IOException {
        //数据来自文本文件

        Socket s =  new Socket("192.168.1.7",10010);

        BufferedReader br = new BufferedReader(new FileReader("F:\\tcp.txt"));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()) );

        String line;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        br.close();
        s.close();
    }
}

练习五:

客户端:数据来自文本文件,接收反馈

服务端:接收到的数据写入文本文件,给出反馈

//ServerDemo5.java
package com.itTCP;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo5 {
    public static void main(String[] args) throws IOException {
        //接收到的数据写入文本文件

        ServerSocket ss  = new ServerSocket(10010);

        Socket s = ss.accept();

        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new FileWriter("F://tcpwrite.txt"));

        String line;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //给出反馈
        BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
        bwServer.write("文件上传成功");
        bwServer.newLine();
        bwServer.flush();

        bw.close();
        ss.close();

    }
}

//ClientDemo.java
package com.itTCP;

import java.io.*;
import java.net.Socket;

public class ClientDemo5 {
    public static void main(String[] args) throws IOException {
        //数据来自文本文件

        Socket s =  new Socket("192.168.1.7",10010);

        BufferedReader br = new BufferedReader(new FileReader("F:\\tcp.txt"));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()) );

        String line;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        s.shutdownOutput();

        BufferedReader brClient  = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String lline = brClient.readLine();
        System.out.println("服务器反馈的数据是:"+lline);

        br.close();
        s.close();
    }
}

出现的问题:程序一直等待

原因:读数据的方式是阻塞式的

解决办法:自定义结束标记,使用shutdownOutput()方法(推荐)

练习六:

客户端:数据来自文本文件,接收反馈

服务端:接收到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程

ServerThread.java
package com.itTCP;

import java.io.*;
import java.net.Socket;

public class ServerThread implements Runnable {
    //接收到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程
    private Socket s;

    public ServerThread(Socket s){
        this.s = s;
    }

    @Override
    public void run() {

        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            int  count = 0;
            File file = new File("F:\\tcp["+count+"].txt");
            while(file.exists()){
                count++;
                file = new File("F:\\tcp["+count+"].txt");
            }
            BufferedWriter bw = new BufferedWriter(new FileWriter(file));

            String line;
            while((line=br.readLine())!=null){
                bw.write(line);
                bw.newLine();
                bw.flush();
            }

            //给出反馈
            BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            bwServer.write("文件上传成功");
            bwServer.newLine();
            bwServer.flush();

            s.close();

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



    }
}

//ServerDemo6.java
package com.itTCP;

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

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

        ServerSocket ss = new ServerSocket(10010);
        while(true){
            Socket s = ss.accept();
            new Thread(new ServerThread(s)).start();
        }
    }
}


//ClientDemo6.java
package com.itTCP;

import java.io.*;
import java.net.Socket;

public class ClientDemo6 {
    public static void main(String[] args) throws IOException {
        //数据来自文本文件

        Socket s =  new Socket("192.168.1.7",10010);

        BufferedReader br = new BufferedReader(new FileReader("F:\\tcp.txt"));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()) );

        String line;
        while((line=br.readLine())!=null){
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        s.shutdownOutput();

        BufferedReader brClient  = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String lline = brClient.readLine();
        System.out.println("服务器反馈的数据是:"+lline);

        br.close();
        s.close();
    }
}

 

你可能感兴趣的:(java)