> Java > java지도 시간 > JAVA 고급 학습 소켓 프로그래밍

JAVA 고급 학습 소켓 프로그래밍

WBOY
풀어 주다: 2022-11-16 16:17:11
앞으로
2341명이 탐색했습니다.

이 기사에서는 소켓 프로그래밍에 대한 관련 내용을 주로 소개하는 java에 대한 관련 지식을 제공합니다. 소켓은 네트워크 드라이버 계층에서 애플리케이션에 제공하는 인터페이스 또는 메커니즘에 대해 함께 살펴보시기 바랍니다. 모두를 돕습니다.

JAVA 고급 학습 소켓 프로그래밍

추천 학습: "java 비디오 튜토리얼"

1. 소켓 지식

1. 소켓 개요

(1) Java는 원래 네트워크 프로그래밍 언어로 등장했으며 네트워크를 통해 클라이언트와 서버 간의 원활한 통신을 실현합니다.

(2) 네트워크 프로그래밍에서는 소켓이 가장 많이 사용되며 모든 실제 네트워크 프로그램에서 소켓 참여가 필수적입니다.

(3) 컴퓨터 네트워크 프로그래밍 기술에서는 두 개의 프로세스 또는 두 개의 컴퓨터가 네트워크 통신 연결을 통해 데이터를 교환할 수 있습니다. 이 통신 링크의 끝점을 "소켓"(영어 이름)이라고 합니다.

(4) 소켓은 네트워크 드라이버 계층에서 애플리케이션에 제공하는 인터페이스 또는 메커니즘입니다.

(5) 물류의 예를 사용하여 특급 배송을 설명합니다. 소켓:

    —>발송인은 수취인의 주소 정보와 함께 상품을 특급 스테이션으로 배송합니다. 발송인은 물류 상태에 대해 신경 쓸 필요가 없습니다. 수취인이 위치한 지역의 특급 배송소로 배송이 진행되며, 수취인은 상품 수령을 기다립니다.

    —> 이 과정은 네트워크에서 정보가 전달되는 과정을 생생하게 보여줍니다. 그 중 상품은 데이터 정보이고, 두 개의 특급 배송 사이트는 두 개의 엔드포인트 소켓입니다.

(6) 애플리케이션은 네트워크에서 정보가 어떻게 처리되고 전송되는지 신경 쓸 필요가 없으며 데이터 전송 및 수신 준비만 담당합니다.

2. 소켓 통신 원리

(1) 프로그래머는 소켓의 기본 메커니즘이 데이터를 전송하는 방식을 이해할 필요가 없으며, 데이터를 소켓에 직접 제출하면 소켓이 해당 데이터를 기반으로 하는 프로그램을 통해 전달합니다. 애플리케이션이 제공하는 일련의 계산, IP 및 정보 데이터 바인딩, 데이터를 드라이버에 전달하여 네트워크로 전송합니다.

(2) Socket의 기본 메커니즘은 매우 복잡합니다. Java 플랫폼은 기본 메커니즘을 알지 못해도 Socket을 사용하여 쉽고 효과적으로 통신 프로그램을 개발할 수 있는 간단하지만 강력한 클래스를 제공합니다.

3. java.net 패키지

(1) java.net 패키지는 소켓 기반 클라이언트/서버 통신을 지원하는 여러 클래스를 제공합니다.

(2) java.net 패키지에서 일반적으로 사용되는 클래스에는 Socket, ServerSocket, DatagramPacket, DatagramSocket, InetAddress, URL, URLConnection 및 URLEncoder 등이 포함됩니다.

(3) 클라이언트의 연결 요청을 모니터링하려면 ServerSocket 클래스를 사용할 수 있습니다.

(4) Socket 클래스는 네트워크의 프로세스 간 통신을 위한 소켓을 구현합니다.

(5) DatagramSocket 클래스는 UDP 프로토콜을 사용하여 클라이언트 및 서버 소켓을 구현합니다.

(6) DatagramPacket 클래스는 DatagramSocket 클래스의 개체를 사용하여 설정과 수신된 데이터그램을 캡슐화합니다.

(7) InetAddress 클래스는 인터넷 주소를 나타냅니다.

(8) 데이터그램 메시지 및 소켓 객체 생성 시 InetAddress 클래스를 사용할 수 있습니다.

2. TCP 프로토콜 기반 소켓 프로그래밍

1. 소켓 클래스 및 ServerSocket 클래스

(1) java.net 패키지의 두 클래스인 Socket과 ServerSocket은 각각 양방향 보안 연결의 클라이언트와 서버를 구현하는 데 사용됩니다. 작업 프로세스는 둘 다 전화를 거는 프로세스와 같습니다. 상대방이 연결되면 통화를 시작할 수 있습니다.

(2) 네트워크 통신 중에 소켓은 데이터 흐름을 사용하여 데이터 전송을 완료해야 합니다.

(3) 네트워크를 통해 다른 애플리케이션으로 데이터를 전송하기 위해 애플리케이션은 간단히 소켓을 생성한 다음 소켓과 연결된 출력 스트림에 데이터를 씁니다. 이에 따라 수신 애플리케이션은 소켓을 생성하고 연결된 입력 스트림에서 데이터를 읽습니다.

(4) 참고: TCP 프로토콜을 기반으로 하는 소켓 프로그래밍에서는 두 엔드포인트가 클라이언트 역할을 하고 다른 엔드포인트는 서버 역할을 하는 경우가 많습니다. 이는 클라이언트-서버 모델을 따른다는 의미입니다.

● 소켓 클래스

소켓 개체는 클라이언트와 서버 간의 연결을 설정합니다. Socket 클래스의 생성자 메서드를 사용하여 소켓을 만들고 이 소켓을 지정된 호스트 및 포트에 연결할 수 있습니다.

(1) 생성 방법

    —>첫 번째 생성 방법은 호스트 이름과 포트 번호를 매개변수로 사용하여 소켓 객체를 생성합니다. 개체를 생성할 때 UnknownHostException 또는 IOException이 발생할 수 있으며 이를 반드시 잡아야 합니다.

소켓 s = 새 소켓(호스트 이름, 포트);

   —>두 번째 생성 방법은 InetAddress 개체와 포트 번호를 매개 변수로 사용하여 소켓 개체를 만듭니다. 생성자는 IOException 또는 UnknownHostException을 발생시킬 수 있으며 이를 포착하고 처리해야 합니다.

Socket s = new Socket(주소, 포트);

(2) 일반적인 방법

● ServerSocket 클래스

ServerSocket 객체는 클라이언트가 연결을 설정할 때까지 기다립니다. 연결이 설정됩니다. 통신은 나중에 만들어지죠.

(1) 생성 방법

  — —>첫 번째 생성 방법은 ServerSocket 개체를 생성하기 위해 포트 번호를 매개 변수로 허용합니다. 이 개체를 생성할 때 IOException이 발생할 수 있으며 이를 포착하여 처리해야 합니다. S Serversocket SS = New Serversocket (Port)

-& GT; and using using using  -->Socket 클래스에 나열된 메서드는 ServerSocket 클래스에도 적용 가능합니다.

     —>ServerSocket 클래스에는 클라이언트가 통신을 시작하여 추가 데이터 전송에 Socket 객체를 사용할 수 있을 때까지 기다리는 데 사용되는 accept() 메서드가 있습니다.

2. 소켓 프로그래밍을 사용하여 로그인 기능 구현

● 단일 사용자 로그인을 구현하려면

- -->소켓 네트워크 프로그래밍은 일반적으로 다음 4단계로 나뉩니다.


(1 ) 연결을 설정합니다.

(2) 소켓과 연결된 입력/출력 스트림을 엽니다.

(3) 데이터 스트림에서 정보를 쓰고 정보를 읽습니다.

(4) 모든 데이터 스트림과 소켓을 닫습니다. -& gt; 사용자 로그인 기능을 시뮬레이션하고 클라이언트가 사용자 로그인 정보를 서버 측으로 보내고 서버 측에 정보를 표시하는 데 두 가지 클래스를 사용합니다.步 클라이언트 구현 단계:

1) 연결을 설정하고 서버와 포트에 연결합니다.

2) 소켓과 연관된 입력/출력 스트림을 엽니다.

3) 출력 스트림에 정보를 씁니다.

4) 입력 스트림에서 응답 정보를 읽습니다.

5) 모든 데이터 스트림과 소켓을 닫습니다.

서버측 구현 단계:

1) 연결을 설정하고 포트에서 수신 대기합니다.

2) accept() 메서드를 사용하여 클라이언트가 통신을 시작할 때까지 기다립니다.

3) 소켓과 연결된 입력/출력 스트림을 엽니다.

4) 입력 스트림에서 요청 정보를 읽습니다.

5) 출력 스트림에 정보를 씁니다.

            6) 모든 데이터 스트림과 소켓을 닫습니다. -& gt; 클라이언트와 서버의 상호 작용은 응답 모드를 채택하고 먼저 서버를 시작하여 모니터링 상태로 들어가서 클라이언트의 연결 요청을 기다립니다.

예제 01: 객체 정보 전송을 구현합니다.

♥ user 클래스

package cn.bdqn.demo02;

import java.io.Serializable;

public class User implements Serializable {

	private static final long serialVersionUID = 1L;
	/** 用户名 */
	private String loginName;
	/** 用户密码 */
	private String pwd;

	public User() {
		super();
	}

	public User(String loginName, String pwd) {
		super();
		this.loginName = loginName;
		this.pwd = pwd;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

}
로그인 후 복사

♥ LoginServer 클래스

package cn.bdqn.demo02;

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

public class LoginServer {

	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		Socket socket = null;
		InputStream is = null;
		ObjectInputStream ois = null;
		OutputStream os = null;
		try {
			// 建立一个服务器Socket(ServerSocket),指定端口8800并开始监听
			serverSocket = new ServerSocket(8800);
			// 使用accept()方法等待客户端发起通信
			socket = serverSocket.accept();
			// 打开输入流
			is = socket.getInputStream();
			// 反序列化
			ois = new ObjectInputStream(is);
			// 获取客户端信息,即从输入流读取信息
			User user = (User) ois.readObject();
			if (user != null) {
				System.out.println("我是服务器,客户登录信息为:" + user.getLoginName() + ","
						+ user.getPwd());
			}

			// 给客户端一个响应,即向输出流中写入信息
			String reply = "欢迎你,登录成功";
			os = socket.getOutputStream();
			os.write(reply.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			// 关闭资源
			try {
				os.close();
				ois.close();
				is.close();
				socket.close();
				serverSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
로그인 후 복사

LoginClient 클래스

package cn.bdqn.demo02;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class LoginClient {

	/*
	 * 示例02:升级演示示例01,实现传递对象信息。
	 */
	
	public static void main(String[] args) {
		Socket socket = null;
		OutputStream os = null;
		ObjectOutputStream oos = null;
		InputStream is = null;
		BufferedReader br = null;
		try {
			// 建立客户端Socket连接,指定服务器的位置为本机以及端口为8800
			socket = new Socket("localhost", 8800);
			// 打开输出流
			os = socket.getOutputStream();
			// 对象序列化
			oos = new ObjectOutputStream(os);
			// 发送客户端信息,即向输出流中写入信息
			User user = new User("Tom", "123456");
			oos.writeObject(user);
			socket.shutdownOutput();

			// 接收服务器端的响应,即从输入流中读取信息
			is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			String reply;
			while ((reply = br.readLine()) != null) {
				System.out.println("我是客户端,服务器的响应为:" + reply);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				is.close();
				oos.close();
				os.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
로그인 후 복사

예제 02: 데모 예제 01을 업그레이드하여 다중 객체 정보 전송을 구현합니다.

user class

package cn.bdqn.demo03;

import java.io.Serializable;

public class User implements Serializable {

	private static final long serialVersionUID = 1L;
	/** 用户名 */
	private String loginName;
	/** 用户密码 */
	private String pwd;

	public User() {
		super();
	}

	public User(String loginName, String pwd) {
		super();
		this.loginName = loginName;
		this.pwd = pwd;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

}
로그인 후 복사

LoginServer class

package cn.bdqn.demo03;

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

public class LoginServer {

	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		Socket socket = null;
		InputStream is = null;
		ObjectInputStream ois = null;
		OutputStream os = null;
		try {
			// 建立一个服务器Socket(ServerSocket),指定端口8800并开始监听
			serverSocket = new ServerSocket(8800);
			// 使用accept()方法等待客户端发起通信
			socket = serverSocket.accept();
			// 打开输入流
			is = socket.getInputStream();
			// 反序列化
			ois = new ObjectInputStream(is);
			// 获取客户端信息,即从输入流读取信息
			User[] users = (User[]) ois.readObject();
			for (int i = 0; i < users.length; i++) {
				System.out.println("我是服务器,客户登录信息为:" + users[i].getLoginName()
						+ "," + users[i].getPwd());
			}

			// 给客户端一个响应,即向输出流中写入信息
			String reply = "欢迎你,登录成功";
			os = socket.getOutputStream();
			os.write(reply.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			// 关闭资源
			try {
				os.close();
				ois.close();
				is.close();
				socket.close();
				serverSocket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
로그인 후 복사

LoginClient class

package cn.bdqn.demo03;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class LoginClient {

	/*
	 * 示例02:升级演示示例01,实现传递对象信息。
	 */
	
	public static void main(String[] args) {
		Socket socket = null;
		OutputStream os = null;
		ObjectOutputStream oos = null;
		InputStream is = null;
		BufferedReader br = null;
		try {
			// 建立客户端Socket连接,指定服务器的位置为本机以及端口为8800
			socket = new Socket("localhost", 8800);
			// 打开输出流
			os = socket.getOutputStream();
			// 对象序列化
			oos = new ObjectOutputStream(os);
			// 发送客户端信息,即向输出流中写入信息
			User user1 = new User("Tom", "123456");
			User user2 = new User("bob", "123456");
			User user3 = new User("lisa", "123456");
			User[] users = {user1,user2,user3};
			oos.writeObject(users);
			socket.shutdownOutput();

			// 接收服务器端的响应,即从输入流中读取信息
			is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			String reply;
			while ((reply = br.readLine()) != null) {
				System.out.println("我是客户端,服务器的响应为:" + reply);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				is.close();
				oos.close();
				os.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
로그인 후 복사

● 멀티 클라이언트 사용자 로그인 구현

--> 원하다. 서버는 하나의 클라이언트에만 서비스를 제공할 수 없으며 일반적으로 동시에 여러 클라이언트에 서비스를 제공합니다. 그러나 결과적으로 단일 스레드 구현이 이루어져야 합니다.

    —>이 문제를 해결하는 방법은 멀티스레딩을 사용하는 것입니다. 서버 측에서 모니터링을 담당하는 응용 프로그램 기본 서비스 프로그램과 응답을 특별히 담당하는 스레드 프로그램을 만들 수 있습니다. 이를 통해 멀티스레딩이 여러 요청을 처리할 수 있습니다. ;-& Gt; 클라이언트 구현 단계:

1) 연결을 생성하고 서버와 포트에 연결합니다.

2) 소켓과 연관된 입력/출력 스트림을 엽니다.

3) 출력 스트림에 정보를 씁니다.

4) 입력 스트림에서 응답 정보를 읽습니다.

5) 모든 데이터 스트림과 소켓을 닫습니다. -& gt; 서버 측 구현 단계:

1) 요청에 대한 응답을 얻기 위해 서버 스레드 클래스와 Run() 메서드를 만듭니다.

2) 서버측 소켓이 항상 리스닝 상태가 되도록 서버측 코드를 수정합니다.

3) 서버는 요청을 들을 때마다 스레드 객체를 생성하고 시작합니다.

예제 03: 데모 예 02를 업그레이드하여 다중 클라이언트 응답 처리를 구현합니다.

사용자 클래스

package cn.bdqn.demo04;

import java.io.Serializable;

public class User implements Serializable {

	private static final long serialVersionUID = 1L;
	/** 用户名 */
	private String loginName;
	/** 用户密码 */
	private String pwd;

	public User() {
		super();
	}

	public User(String loginName, String pwd) {
		super();
		this.loginName = loginName;
		this.pwd = pwd;
	}

	public String getLoginName() {
		return loginName;
	}

	public void setLoginName(String loginName) {
		this.loginName = loginName;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

}
로그인 후 복사
LoginThread

package cn.bdqn.demo04;

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

public class LoginThread extends Thread {
	/*
	 * 示例03:升级示例02,实现多客户端的响应处理。
	 * 
	 * 分析如下:
	 * 	(1)创建服务器端线程类,run()方法中实现对一个请求的响应处理。
	 * 	(2)修改服务器端代码,让服务器端Socket一直处于监听状态。
	 * 	(3)服务器端每监听到一个请求,创建一个线程对象并启动
	 */
	
	Socket socket = null;
	//每启动一个线程,连接对应的Socket

	public LoginThread(Socket socket) {
		this.socket = socket;
	}
	
	//启动线程,即响应客户请求
	public void run() {
		InputStream is = null;
		ObjectInputStream ois = null;
		OutputStream os = null;
		try {
			//打开输入流
			is = socket.getInputStream();
			//反序列化
			ois = new ObjectInputStream(is);
			//获取客户端信息,即从输入流读取信息
			User user = (User)ois.readObject();
			if(user!=null){
				System.out.println("我是服务器,客户登录信息为:"+user.getLoginName()+","+user.getPwd());
			}
			
			//给客户端一个响应,即向输出流中写入信息
			os = socket.getOutputStream();
			String reply = "欢迎你,登录成功";
			os.write(reply.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}finally{
			try {
				os.close();
				ois.close();
				is.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}			
		}	
	}	
}
로그인 후 복사
LoginServer 클래스

package cn.bdqn.demo04;

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

public class LoginServer {
	
	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		try {
			// 建立一个服务器Socket(ServerSocket)指定端口并开始监听
			serverSocket = new ServerSocket(8800);

			// 监听一直进行中
			while (true) {
				// 使用accept()方法等待客户发起通信
				Socket socket = serverSocket.accept();
				LoginThread loginThread = new LoginThread(socket);
				loginThread.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
로그인 후 복사
♥ LoginClient1 클래스

package cn.bdqn.demo04;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class LoginClient01 {
	/*
	 * 客户端通过输出流向服务器端发送请求信息
	 * 服务器侦听客户端的请求得到一个Socket对象,将这个Socket对象传递给线程类
	 * 线程类通过输入流获取客户端的请求并通过输出流向客户端发送响应信息
	 * 客户端通过输入流读取服务器发送的响应信息
	 * 
	 */

	/*
	 * 示例03:升级演示示例02,实现多客户端的响应处理
	 */
	public static void main(String[] args) {
		
		Socket socket = null;
		OutputStream os = null;
		ObjectOutputStream oos = null;
		InputStream is = null;
		BufferedReader br = null;
		try {
			// 建立客户端Socket连接,指定服务器的位置为本机以及端口为8800
			socket = new Socket("localhost", 8800);
			// 打开输出流
			os = socket.getOutputStream();
			// 对象序列化
			oos = new ObjectOutputStream(os);
			// 发送客户端信息,即向输出流中写入信息
			User user = new User("Tom", "123456");
			oos.writeObject(user);
			socket.shutdownOutput();

			// 接收服务器端的响应,即从输入流中读取信息
			is = socket.getInputStream();
			br = new BufferedReader(new InputStreamReader(is));
			String reply;
			while ((reply = br.readLine()) != null) {
				System.out.println("我是客户端,服务器的响应为:" + reply);
			}
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
				is.close();
				oos.close();
				os.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
로그인 후 복사
♥ LoginClient2 클래스 및 LoginClient3 클래스

LoginClient1 클래스와 동일, 다른 사용자 개체 생성 가능

    —> java.net 패키지의 InetAddress 클래스는 IP 주소와 DNS를 캡슐화하는 데 사용됩니다. InetAddress 클래스의 인스턴스를 생성하려면 이 클래스에 생성자가 없으므로 팩토리 메서드를 사용할 수 있습니다. -& gt; InetAddress 클래스의 팩토리 메소드

-& gt; 호스트를 찾을 수 없으면 두 메소드 모두 UnknownHostnameException 이상을 발생시킵니다.

3. UDP 프로토콜 기반 소켓 프로그래밍

TCP UDP연결 지향신뢰할 수 있음느림

1. DatagramPacket 클래스 및 DatagramSocket 클래스

(1) TCP 기반 네트워크 통신은 안전하고 양방향입니다. 전화 통화와 마찬가지로 먼저 서버가 필요하며 데이터 통신이 가능하기 전에 양방향 연결이 설정됩니다. 시작하다.

(2) UDP 기반 네트워크 통신은 사전 연결 없이 상대방의 주소만 지정한 후 데이터를 전송하면 됩니다. 이러한 네트워크 통신은 안전하지 않으므로 채팅 시스템, 상담 시스템 등의 상황에서만 사용됩니다.

(3) 데이터그램은 통신을 나타내는 메시지의 일종으로, 데이터그램을 통신에 사용하는 경우에는 UDP 프로토콜을 기반으로 하므로 미리 연결을 설정할 필요가 없습니다.

(4) Java에는 데이터그램을 사용하여 통신을 구현할 수 있는 두 가지 클래스, 즉 DatagramPacketDatagramSocket이 있습니다.

(5) DatagramPacket 클래스는 컨테이너 역할을 하며 DatagramSocket 클래스는 DatagramPacket을 보내거나 받는 데 사용됩니다.

(6)DatagramPacket 클래스는 데이터를 보내고 받는 메소드를 제공하지 않는 반면, DatagramSocket 클래스는 소켓을 통해 데이터그램을 보내고 받는 send()메서드와 receive()메서드를 제공합니다.

● DatagramPacket 클래스

(1) 구성 방법

                                            ~         .

(2) 공통 메소드

● DatagramSocket 클래스

(1) 구성 메소드

--> DatagramSocket 클래스는 연결 상태를 유지하지 않으며 입출력 데이터 스트림을 생성하지 않습니다. 유일한 기능은 DatagramPacket 개체로 캡슐화된 데이터그램을 받고 보내는 것입니다.

(2) 일반적인 방법

2. 소켓 프로그래밍을 사용하여 고객 상담 구현

                                                                                                                     P2P(Peer-to-Peer) 방식에서는 기본과 보조 사이에 차이가 없으며 해당 코드도 정확히 이는 TCP 프로토콜 기반의 소켓 프로그래밍과 구별되어야 합니다. -& gt; UDP 프로토콜을 기반으로 하는 소켓 네트워크 프로그래밍은 일반적으로 다음 4단계를 기반으로 합니다.

(1) DataGrampacket 개체를 사용하여 데이터 패킷을 캡슐화합니다.

              (2) DatagramSocket 객체를 사용하여 데이터 패킷을 보냅니다.

              (3) DatagramSocket 객체를 사용하여 데이터 패킷을 수신합니다.

              (4) DatagramPacket 객체를 사용하여 데이터 패킷을 처리합니다.

      —>발신자는 상담 질문을 보내고 수신자는 보낸 상담 질문을 수신하고 표시하는 고객 상담 기능을 시뮬레이션합니다.

            발신자 구현 단계:

                    1) 로컬 호스트의 InetAddress 개체를 얻습니다.

2) 전송할 정보를 캡슐화하는 DatagramPacket 개체를 만듭니다.

3) DatagramSocket 개체를 사용하여 DatagramPacket 개체 데이터를 보냅니다.

수신기 구현 단계:

1) DatagramPacket 객체를 생성하고 캡슐화된 데이터를 수신할 준비를 합니다.

                2)创建DatagramSocket对象,接收数据保存于DatagramPacket对象中。

                3)利用DatagramPacket对象处理数据。

示例04:发送方发送咨询问题,接收方回应咨询。

♥ Receive类

package cn.bdqn.demo05;

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

public class Receive {

	public static void main(String[] args) {
		/*
		 * 示例06:发送方发送咨询问题,接收方回应咨询。
		 * 
		 * 接收方实现步骤如下: 
		 * (1)创建DatagramPacket对象,准备接收封装的数据。
		 * (2)创建DatagramSocket对象,接收数据保存于DatagramPacket对象中。
		 * (3)利用DatagramPacket对象处理数据。
		 */

		DatagramSocket ds = null;
		DatagramPacket dp = null;
		DatagramPacket dpto = null;
		// 创建DatagramPacket对象,用来准备接收数据
		byte[] buf = new byte[1024];
		dp = new DatagramPacket(buf, 1024);
		try {
			// 创建DatagramSocket对象,接收数据
			ds = new DatagramSocket(8800);
			ds.receive(dp);
			// 显示接收到的信息
			String mess = new String(dp.getData(), 0, dp.getLength());
			System.out.println(dp.getAddress().getHostAddress() + "说:" + mess);

			String reply = "你好,我在,请咨询!";
			// 显示与本地对话框
			System.out.println("我  说:" + reply);
			// 创建DatagramPacket对象,封装数据
			SocketAddress sa = dp.getSocketAddress();
			dpto = new DatagramPacket(reply.getBytes(),
					reply.getBytes().length, sa);
			ds.send(dpto);
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			ds.close();
		}
	}
}
로그인 후 복사

♥ Send类

package cn.bdqn.demo05;

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

public class Send {
	/*
	 * 示例06:升级示例05,发送方发送咨询问题,接收方回应咨询。
	 * 
	 * 发送方实现步骤如下: 
	 * (1)获取本地主机的InetAddress对象。 
	 * (2)创建DatagramPacket对象,封装要发送的信息。
	 * (3)利用DatagramSocket对象将DatagramPacket对象数据发送出去。
	 */

	public static void main(String[] args) {
		DatagramSocket ds = null;
		InetAddress ia = null;
		String mess = "你好,我想咨询一个问题。";
		System.out.println("我说:" + mess);
		try {
			// 获取本地主机地址
			ia = InetAddress.getByName("localhost");
			// 创建DatagramPacket对象,封装数据
			DatagramPacket dp = new DatagramPacket(mess.getBytes(),
					mess.getBytes().length, ia, 8800);
			// 创建DatagramSocket对象,向服务器发送数据
			ds = new DatagramSocket();
			ds.send(dp);

			byte[] buf = new byte[1024];
			DatagramPacket dpre = new DatagramPacket(buf, buf.length);
			ds.receive(dpre);
			// 显示接收到的信息
			String reply = new String(dpre.getData(), 0, dpre.getLength());
			System.out.println(dpre.getAddress().getHostAddress() + "说:"
					+ reply);
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			ds.close();
		}
	}
}
로그인 후 복사

推荐学习:《java视频教程


연결 여부
연결이 아닌 방향 신뢰할 수 있는 전송 섹스
신뢰할 수 없음 속도
빠름

위 내용은 JAVA 고급 학습 소켓 프로그래밍의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:csdn.net
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿