이 기사에서는 소켓 프로그래밍에 대한 관련 내용을 주로 소개하는 java에 대한 관련 지식을 제공합니다. 소켓은 네트워크 드라이버 계층에서 애플리케이션에 제공하는 인터페이스 또는 메커니즘에 대해 함께 살펴보시기 바랍니다. 모두를 돕습니다.
추천 학습: "java 비디오 튜토리얼"
(1) Java는 원래 네트워크 프로그래밍 언어로 등장했으며 네트워크를 통해 클라이언트와 서버 간의 원활한 통신을 실현합니다.
(2) 네트워크 프로그래밍에서는 소켓이 가장 많이 사용되며 모든 실제 네트워크 프로그램에서 소켓 참여가 필수적입니다.
(3) 컴퓨터 네트워크 프로그래밍 기술에서는 두 개의 프로세스 또는 두 개의 컴퓨터가 네트워크 통신 연결을 통해 데이터를 교환할 수 있습니다. 이 통신 링크의 끝점을 "소켓"(영어 이름)이라고 합니다.
(4) 소켓은 네트워크 드라이버 계층에서 애플리케이션에 제공하는 인터페이스 또는 메커니즘입니다.
(5) 물류의 예를 사용하여 특급 배송을 설명합니다. 소켓:
—>발송인은 수취인의 주소 정보와 함께 상품을 특급 스테이션으로 배송합니다. 발송인은 물류 상태에 대해 신경 쓸 필요가 없습니다. 수취인이 위치한 지역의 특급 배송소로 배송이 진행되며, 수취인은 상품 수령을 기다립니다.
—> 이 과정은 네트워크에서 정보가 전달되는 과정을 생생하게 보여줍니다. 그 중 상품은 데이터 정보이고, 두 개의 특급 배송 사이트는 두 개의 엔드포인트 소켓입니다.
(6) 애플리케이션은 네트워크에서 정보가 어떻게 처리되고 전송되는지 신경 쓸 필요가 없으며 데이터 전송 및 수신 준비만 담당합니다.
(1) 프로그래머는 소켓의 기본 메커니즘이 데이터를 전송하는 방식을 이해할 필요가 없으며, 데이터를 소켓에 직접 제출하면 소켓이 해당 데이터를 기반으로 하는 프로그램을 통해 전달합니다. 애플리케이션이 제공하는 일련의 계산, IP 및 정보 데이터 바인딩, 데이터를 드라이버에 전달하여 네트워크로 전송합니다.
(2) Socket의 기본 메커니즘은 매우 복잡합니다. Java 플랫폼은 기본 메커니즘을 알지 못해도 Socket을 사용하여 쉽고 효과적으로 통신 프로그램을 개발할 수 있는 간단하지만 강력한 클래스를 제공합니다.
(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 클래스를 사용할 수 있습니다.
(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단계로 나뉩니다.(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;
}
}
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 클래스♥ LoginClient1 클래스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(); } } }로그인 후 복사♥ LoginClient2 클래스 및 LoginClient3 클래스 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(); } } } }로그인 후 복사—> java.net 패키지의 InetAddress 클래스는 IP 주소와 DNS를 캡슐화하는 데 사용됩니다. InetAddress 클래스의 인스턴스를 생성하려면 이 클래스에 생성자가 없으므로 팩토리 메서드를 사용할 수 있습니다. -& gt; InetAddress 클래스의 팩토리 메소드
-& gt; 호스트를 찾을 수 없으면 두 메소드 모두 UnknownHostnameException 이상을 발생시킵니다.
3. UDP 프로토콜 기반 소켓 프로그래밍
TCP연결 여부 | ||
연결이 아닌 방향 | 신뢰할 수 있는 전송 섹스 | |
신뢰할 수 없음 | 속도 | |
빠름 |
위 내용은 JAVA 고급 학습 소켓 프로그래밍의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!