네트워크 프로그래밍 및 HTTP 요청

목차

IP 및 포트 운영

커뮤니케이션 관련

소켓

TCP 프로토콜

특징:

TCP 연습 동작 

고객

섬기는 사람

UDP 프로토콜

특징:

UDP 연습 작업 

보내는 사람

수화기

자바 HTTP 요청

요청을 수신하기 위해 tomcat 서비스를 엽니다.

HTTP는 GET 요청을 보냅니다.

HTTP 전송 POST 요청

알아채다:

IP 및 포트 운영

  • 클래스: InetAddress - IP 캡슐화
  • 클래스: InetSocketAddress - IP, 포트 캡슐화

참고: IP와 포트를 직접 조작할 수 없으며 개체 작업으로 캡슐화해야 합니다.

InetAddress는 생성자 권한 수정자가 기본값이기 때문에 객체를 직접 생성할 수 없지만 클래스 이름을 통해 직접 호출할 수 있는 정적 메서드가 있습니다.

InetAddress address = InetAddress.getByName("localhost");
System.out.println(address);//域名/IP地址
//getByName()中可以封装ip、域名等可以与ip映射的东西
System.out.println(address.getHostName());//获取域名
System.out.println(address.getHostAddress());//获取ip地址
 
//关于类InetSocketAddress
InetSocketAddress inetSocketAddress = new InetSocketAddress("192.168.199.217", 8080);
System.out.println(inetSocketAddress.getHostName());//获得域名
System.out.println(inetSocketAddress.getPort());//获得端口号
InetAddress address1 = inetSocketAddress.getAddress();//获得ip地址对象
System.out.println(address1.getHostName());//获得域名
System.out.println(address1.getHostAddress());//获得IP地址

커뮤니케이션 관련

  • TCP/IP 아키텍처: 네트워크 통신의 기반.
  • 통신을 위한 두 가지 중요한 조건: IP+port(포트)
  • 통신 프로토콜: 장치 간에 데이터를 전송할 때는 일정한 규칙을 따라야 하는데 이 규칙을 통신 프로토콜이라고 합니다.

소켓

역할: 애플리케이션 계층은 전송 계층 프로토콜(TCP/UDP)을 얻습니다.

TCP 프로토콜

이름: 전송 제어 프로토콜

특징:

  • 신뢰할 수 있는 연결 지향적
  • 연결을 설정하기 위해 3번의 핸드셰이크가 설정되고 연결을 해제하기 위해 4번의 핸드셰이크가 해제됩니다.

알아채다:

  • 클라이언트 요청을 기다리기 위해 먼저 서버를 열어야 함
  • 클라이언트와 서버 간의 양방향 통신, 클라이언트가 연결을 닫고 싶습니다 입력하면 연결을 닫습니다.

TCP 연습 동작 

고객

public class Customer {
    public static void main(String[] args) throws IOException {
        //创建套接字,指定服务器的IP和端口
        Socket socket = new Socket("127.0.0.1", 6666);
        socket.setSoTimeout(1000000);//设置连接超时时间,以ms为单位
        OutputStream outputStream = socket.getOutputStream();//获取输出流用来发送数据
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);//变成可处理字符串的输出流——装饰模式
        InputStream inputStream = socket.getInputStream();//获取输入流用来读数据
        DataInputStream dataInputStream = new DataInputStream(inputStream);//变成可处理字符串的输入流——装饰模式
        String s1="";
        while(!s1.equals("关闭")) {
            String s = new Scanner(System.in).nextLine();
            dataOutputStream.writeUTF(s);//给服务器发送数据——不阻塞
            s1 = dataInputStream.readUTF();//读取服务端信息——其为阻塞方法
            System.out.println(s1);
        }
        //以下为关流
        dataOutputStream.close();
        outputStream.close();
        socket.close();
    }
}

섬기는 사람

public class Service {
    public static void main(String[] args) throws IOException {
        //创建套接字,监听6666端口
        ServerSocket serverSocket = new ServerSocket(6666);
        //accept()为阻塞方法,等待用户端数据,什么时候收到数据什么时候执行,返回值为客户端socket,接到这个socket后,客户端和服务器才真正建立连接,才真正可以通信了
        Socket accept = serverSocket.accept();
        InputStream inputStream = accept.getInputStream();//获取输入流,用来得到客户端数据
        DataInputStream dataInputStream = new DataInputStream(inputStream);//利用字符串处理流来读取字符串
        OutputStream outputStream = accept.getOutputStream();//获取输出流,用来向客户端写数据
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
        String s1="";
        while(!s1.equals("关闭")) {
            String s = dataInputStream.readUTF();//读取客户端数据——其为阻塞方法
            System.out.println(s);//信息
            if(s.equals("我想关闭连接")){
                s1="关闭";
                dataOutputStream.writeUTF(s1);
            }else {
                s1 = new Scanner(System.in).nextLine();
                dataOutputStream.writeUTF(s1);//不阻塞
            }
        }
        //以下为关流
        dataInputStream.close();
        inputStream.close();
        accept.close();//客户端socket
        serverSocket.close();
    }
}//全写好之后运行该服务等待客户端请求

UDP 프로토콜

이름: 사용자 데이터그램 프로토콜

특징:

  • 비연결 지향
  • 데이터 패킷을 분할하여 하나씩 대상으로 보내고 마지막으로 서버 측에서 요약합니다(패킷 손실 문제가 있음).

알아채다:

  • 보내는 사람과 받는 사람이 같다
  • 발신자와 수신자 간의 양방향 통신, 발신자가 다음 채팅에 들어가면 중지

UDP 연습 작업 

보내는 사람

public class Send {
    public static void main(String[] args) throws IOException {
        //准备套接字,指定发送方的端口号
        DatagramSocket datagramSocket = new DatagramSocket(8888);
        String s1="";
        while(!s1.equals("bye bye")) {
            //发送阶段
            //准备数据包
            String s = new Scanner(System.in).nextLine();
            byte[] bytes = s.getBytes();
            //里面传接收方的IP地址对象及端口
            DatagramPacket localhost = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"), 6666);
            //向目标地址发送数据包
            datagramSocket.send(localhost);//不是阻塞方法
 
            //接收阶段
            byte[] b = new byte[1024];
            DatagramPacket datagramPacket = new DatagramPacket(b, b.length);
            datagramSocket.receive(datagramPacket);
            byte[] data = datagramPacket.getData();
            s1 = new String(data, 0, datagramPacket.getLength());
            System.out.println(s1);
        }
        //关流
        datagramSocket.close();
    }
}

수화기

public class Get {
    public static void main(String[] args) throws IOException {
        DatagramSocket datagramSocket = new DatagramSocket(6666);//指定接收方的端口号
        boolean flag=true;
        while(flag) {
            //接收阶段
            //搞一个空数据包用来接收对方传过来的数据
            byte[] bytes = new byte[1024];
            DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
            //接收对方发过来的数据包放入datagramPacket数据包中进行填充
            datagramSocket.receive(datagramPacket);//其为阻塞方法,接收数据包后,datagramPacket里面的内容就填充好了
            //取出数据
            byte[] data = datagramPacket.getData();
            String s = new String(data, 0, datagramPacket.getLength());//取出特定长度的字节数据转化为字符串类型
            System.out.println(s);
            if(s.equals("下次再聊")){
                DatagramPacket end = new DatagramPacket("bye bye".getBytes(), "bye bye".getBytes().length, InetAddress.getByName("localhost"), 8888);
                datagramSocket.send(end);
                flag=false;
            }else {
                //发送阶段
                //准备数据包
                String s1 = new Scanner(System.in).nextLine();
                byte[] b = s1.getBytes();
                DatagramPacket localhost = new DatagramPacket(b, b.length, InetAddress.getByName("localhost"), 8888);
                //向目标地址发送数据包
                datagramSocket.send(localhost);//不是阻塞方法
            }
        }
        //关流
        datagramSocket.close();
    }
}

자바 HTTP 요청

요청을 수신하기 위해 tomcat 서비스를 엽니다.

@RestController
@RequestMapping("/hello")
public class MyController {
    @GetMapping("/getName")
    public String responseName(String name){
        return "你的名字为"+name;
    }
    @PostMapping("/getUser")
    public String responseUser(@RequestBody Map<String,Object> map){
        System.out.println(map);
        return "你的post请求发送成功";
    }
}

참고: 여기서 사용한 포트는 8088입니다.

HTTP는 GET 요청을 보냅니다.

public class HttpTest {
    public static void main(String[] args) throws Exception{
        //定义一个url字符串
        String urlstr = "http://localhost:8088/hello/getName?name=lili";
        //将url字符串转换为url对象
        URL url = new URL(urlstr);
        //通过该url对象创建连接
        URLConnection urlConnection = url.openConnection();
        //URLConnection为一个抽象类,我们需要HttpURLConnection
        HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
        //使用url.openConnection()创建了连接,connect()方法可有可无;
        //如果使用HttpURLConnection conn=new HttpURLConnection(new URL(“路径”)),则需要使用connect()方法进行连接。
        //httpURLConnection.connect();
        //设置请求头
        httpURLConnection.setRequestProperty("Accept-Charset", "utf-8");
        //设置请求类型
        httpURLConnection.setRequestMethod("GET");
        //设置连接超时时间10s
        httpURLConnection.setConnectTimeout(10000);
        //设置读取超时时间10秒
        httpURLConnection.setReadTimeout(10000);
        //允许从远程服务器中读取数据,默认为true
        httpURLConnection.setDoInput(true);
        //获取HttpURLConnection的输入流,用来读数据
        InputStream inputStream = httpURLConnection.getInputStream();
        //装饰模式,处理流对该流进行处理
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
        //该处理流用来增加处理效率
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line;
        StringBuilder all = new StringBuilder();
        //若该行数据不为空,则追加到all
        while ((line = bufferedReader.readLine()) != null) {
            all.append(line);
        }
        System.out.println(all);
        //获得响应状态码
        int responseCode = httpURLConnection.getResponseCode();
        System.out.println(responseCode);
        //关流
        bufferedReader.close();
        inputStreamReader.close();
        inputStream.close();
        //关闭连接
        httpURLConnection.disconnect();
    }
}

HTTP 전송 POST 요청

public class HttpTestPost {
    public static void main(String[] args) throws Exception{
        //定义一个url字符串
        String urlstr = "http://localhost:8088/hello/getUser";
        //将url字符串转换为url对象
        URL url = new URL(urlstr);
        //通过该url对象创建连接
        URLConnection urlConnection = url.openConnection();
        //URLConnection为一个抽象类,我们需要HttpURLConnection
        HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
        //设置请求头
        httpURLConnection.setRequestProperty("appId", "app_service");
        //设置请求类型
        httpURLConnection.setRequestMethod("POST");
        //设置请求体格式,这里设置的是json格式
        httpURLConnection.setRequestProperty("Content-Type", "application/json; charset=utf-8;");
        //设置连接超时时间10s
        httpURLConnection.setConnectTimeout(10000);
        //设置请求体
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("name","lili");
        map.put("age",18);
        //将usermap转化为json格式
        ObjectMapper mapper = new ObjectMapper();
        String jsonBody = mapper.writeValueAsString(map);
        //设置成true,向远程服务器写数据,默认是false
        httpURLConnection.setDoOutput(true);
        OutputStream outputStream = httpURLConnection.getOutputStream();
        outputStream.write(jsonBody.getBytes());
        outputStream.flush();
        //关流
        outputStream.close();
        //允许从远程服务器中读取数据,默认为true
        //httpURLConnection.setDoInput(true);
        //获取HttpURLConnection的输入流,用来读数据
        InputStream inputStream = httpURLConnection.getInputStream();
        //装饰模式,处理流对该流进行处理
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
        //该处理流用来增加处理效率
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line;
        StringBuilder all = new StringBuilder();
        //若该行数据不为空,则追加到all
        while ((line = bufferedReader.readLine()) != null) {
            all.append(line);
        }
        System.out.println(all);
        //获得响应状态码
        int responseCode = httpURLConnection.getResponseCode();
        System.out.println(responseCode);
        //关流
        bufferedReader.close();
        inputStreamReader.close();
        inputStream.close();
        //关闭连接
        httpURLConnection.disconnect();
    }
}

알아채다:

  • 연결을 생성하기 위해 url.openConnection()을 사용한 후에는 연결을 생성할 필요가 없습니다.
  • HttpURLConnection conn=new HttpURLConnection(new URL("path"))를 사용하면 connect() 메서드를 사용하여 연결해야 합니다.
  • httpURLConnection.setDoInput(true) 메소드는 원격 서버에서 데이터 읽기를 허용하는 것입니다. 기본값은 true입니다.
  • httpURLConnection.setDoOutput(true) 메소드는 원격 서버에 데이터 쓰기를 허용하는 것입니다. 기본값은 false입니다.

추천

출처blog.csdn.net/m0_60027772/article/details/129065128