Steckdose ist für uns sehr praktisch. Nachfolgend finden Sie die Anmerkungen zu dieser Studie. Es ist hauptsächlich in Ausnahmetypen, Interaktionsprinzipien, Socket, ServerSocket und Multithreading unterteilt.
Für Echtzeitanwendungen oder Echtzeitspiele kann das HTTP-Protokoll unsere Anforderungen oft nicht erfüllen. Derzeit ist Socket für uns sehr praktisch. Nachfolgend finden Sie die Anmerkungen zu dieser Studie. Es wird hauptsächlich anhand von Ausnahmetypen, Interaktionsprinzipien, Socket, ServerSocket und Multithreading erläutert.
Ausnahmetypen
Bevor Sie den Inhalt von Socket verstehen, müssen Sie zunächst einige der beteiligten Ausnahmetypen verstehen. Die folgenden vier Typen erben alle von IOException, sodass viele von ihnen IOException direkt aufrufen können.
UnkownHostException: Hostname oder IP-Fehler
ConnectException: Der Server hat die Verbindung abgelehnt, der Server wurde nicht gestartet (die Anzahl der Warteschlangen wurde überschritten, die Verbindung wurde abgelehnt)
SocketTimeoutException: Zeitüberschreitung bei der Verbindung
BindException: Das Socket-Objekt kann nicht mit der angegebenen lokalen IP-Adresse oder Portbindung verbunden werden
Interaktionsprozess
Interaktion zwischen Socket und ServerSocket, ich denke, das folgende Bild war sehr detailliert und klar.
Socket-Konstruktor
Socket()
Socket(InetAddress address, int port)throws UnknownHostException, IOException
Socket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException
Socket(String host, int port)throws UnknownHostException, IOException
Socket(String host, int port , InetAddress localAddress, int localPort)wirft IOException
Mit Ausnahme des ersten ohne Parameter werden andere Konstruktoren versuchen, eine Verbindung mit dem Server herzustellen. Wenn dies fehlschlägt, wird ein IOException-Fehler ausgelöst. Bei Erfolg wird das Socket-Objekt zurückgegeben.
InetAddress ist eine Klasse, die zum Aufzeichnen von Hosts verwendet wird. Ihre statische getHostByName(String-Nachricht) kann eine Instanz zurückgeben. Ihre statische Methode getLocalHost() kann auch die IP-Adresse des aktuellen Hosts abrufen und eine Instanz zurückgeben. Die Parameter des Socket-Konstruktors (String host, int port, InetAddress localAddress, int localPort) sind Ziel-IP, Ziel-Port, gebundene lokale IP bzw. gebundener lokaler Port.
Socket-Methode
getInetAddress(); Die IP-Adresse des Remote-Servers
getPort(); der Remote-Server
getLocalAddress() Die IP-Adresse des lokalen Clients
getLocalPort() Der Port des lokalen Clients
getInputStream(); Holen Sie sich den Eingabestream
getOutStream(); Holen Sie sich den Ausgabestream
Es ist erwähnenswert, dass unter diesen Methoden die wichtigsten getInputStream() und getOutputStream() sind.
Socket-Status
isClosed(); //Ob die Verbindung geschlossen ist, sonst true zurückgeben;
isConnect(); //Wenn es schon einmal verbunden war, gib true zurück; andernfalls gib false zurück
isBound(); //Wenn der Socket an einen lokalen Port gebunden wurde, gib false zurück >
Half-close the Socket
Oft wissen wir nicht, wie lange es dauert, den erhaltenen Eingabestream einzulesen, bevor er endet. Im Folgenden sind einige der gebräuchlichsten Methoden aufgeführt:
ServerSocket-Konstruktor
ServerSocket()throws IOException ServerSocket(int port)throws IOException ServerSocket(int port, int backlog)throws IOException ServerSocket(int port, int backlog, InetAddress bindAddr)throws IOException
Hinweis:
1. Der zu überwachende Port vom Port-Server; die Warteschlangenlänge der Backlog-Client-Verbindungsanforderung; bindAddr-Server-Bindungs-IP 2. Wenn der Port belegt ist oder keine Berechtigung zur Verwendung bestimmter Ports hat, wird ein BindException-Fehler ausgelöst. Beispielsweise erfordern die Ports 1–1023, dass Administratoren über die Berechtigung zum Binden verfügen. 3. Wenn der Port auf 0 gesetzt ist, weist das System ihm automatisch einen Port zu;4. bindAddr用于绑定服务器IP,为什么会有这样的设置呢,譬如有些机器有多个网卡。
5. ServerSocket一旦绑定了监听端口,就无法更改。ServerSocket()可以实现在绑定端口前设置其他的参数。
单线程的ServerSocket例子
public void service(){ while(true){ Socket socket=null; try{ socket=serverSocket.accept();//从连接队列中取出一个连接,如果没有则等待 System.out.println("新增连接:"+socket.getInetAddress()+":"+socket.getPort()); ...//接收和发送数据 }catch(IOException e){e.printStackTrace();}finally{ try{ if(socket!=null) socket.close();//与一个客户端通信结束后,要关闭Socket }catch(IOException e){e.printStackTrace();} } } }
多线程的ServerSocket
多线程的好处不用多说,而且大多数的场景都是多线程的,无论是我们的即时类游戏还是IM,多线程的需求都是必须的。下面说说实现方式:
主线程会循环执行ServerSocket.accept();
当拿到客户端连接请求的时候,就会将Socket对象传递给多线程,让多线程去执行具体的操作;
实现多线程的方法要么继承Thread类,要么实现Runnable接口。当然也可以使用线程池,但实现的本质都是差不多的。
这里举例:
下面代码为服务器的主线程。为每个客户分配一个工作线程:
public void service(){ while(true){ Socket socket=null; try{ socket=serverSocket.accept(); //主线程获取客户端连接 Thread workThread=new Thread(new Handler(socket)); //创建线程 workThread.start(); //启动线程 }catch(Exception e){ e.printStackTrace(); } } }
当然这里的重点在于如何实现Handler这个类。Handler需要实现Runnable接口:
class Handler implements Runnable{ private Socket socket; public Handler(Socket socket){ this.socket=socket; } public void run(){ try{ System.out.println("新连接:"+socket.getInetAddress()+":"+socket.getPort()); Thread.sleep(10000); }catch(Exception e){e.printStackTrace();}finally{ try{ System.out.println("关闭连接:"+socket.getInetAddress()+":"+socket.getPort()); if(socket!=null)socket.close(); }catch(IOException e){ e.printStackTrace(); } } } }
当然是先多线程还有其它的方式,譬如线程池,或者JVM自带的线程池都可以。这里就不说明了。
Das obige ist der detaillierte Inhalt vonTeilen von Beispielen für die Socket-Programmierung in Java (Bild). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!