Heim Java javaLernprogramm Einführung in die Socket-Programmierung in Java

Einführung in die Socket-Programmierung in Java

May 28, 2017 am 09:15 AM
java socket 编程

Dieser Artikel stellt hauptsächlich die relevanten Kenntnisse der Java-Socket-Programmierung vorEinführungEs ist sehr gut und hat Referenzwert.

für In Bezug auf die Java-Socket-Programmierung gibt es zwei Konzepte: eines ist ServerSocket und das andere ist Socket. Über Socket wird eine Verbindung zwischen dem Server und dem Client hergestellt, und dann können sie kommunizieren. Erstens überwacht ServerSocket einen bestimmten Port auf der Serverseite. Wenn es feststellt, dass der Client über einen Socket verfügt, und versucht, eine Verbindung zu diesem herzustellen, akzeptiert es die Verbindungsanforderung des Sockets und richtet auf der Serverseite einen entsprechenden Socket für die Kommunikation ein damit. Auf diese Weise gibt es zwei Sockets, einen für den Client und einen für den Server.

Die Kommunikation zwischen Sockets ist eigentlich sehr einfach. Der Server schreibt Dinge in den Ausgabestream des Sockets, und der Client kann den entsprechenden Inhalt über den Eingabestream des Sockets lesen. Zwischen Socket und Socket besteht eine bidirektionale Verbindung, sodass der Client auch Dinge in den entsprechenden Socket-Ausgabestream schreiben kann und dann der entsprechende Socket-Eingabestream auf dem Server den entsprechenden Inhalt lesen kann. Schauen wir uns einige Beispiele für die Kommunikation zwischen dem Server und dem Client an:

1. Der Client schreibt und der Server liest

Servercode


Java-Code

 public class Server { 
 public static void main(String args[]) throws IOException { 
 //为了简单起见,所有的异常信息都往外抛 
 int port = 8899; 
 //定义一个ServerSocket监听在端口8899上 
 ServerSocket server = new ServerSocket(port); 
 //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 
 Socket socket = server.accept(); 
 //跟客户端建立好连接之后,我们就可以获取socket的InputStream,并从中读取客户端发过来的信息了。 
 Reader reader = new InputStreamReader(socket.getInputStream()); 
 char chars[] = new char[64]; 
 int len; 
 StringBuilder sb = new StringBuilder(); 
 while ((len=reader.read(chars)) != -1) { 
  sb.append(new String(chars, 0, len)); 
 } 
 System.out.println("from client: " + sb); 
 reader.close(); 
 socket.close(); 
 server.close(); 
 } 
 }
Nach dem Login kopieren
Der Betrieb des Servers, der Daten aus dem InputStream des Sockets liest, blockiert ebenfalls. Wenn keine Daten aus dem Eingabestream gelesen werden, wird das Programm dies immer tun Es wird nicht verschoben, bis der Client Daten in den Ausgabestream des Sockets schreibt oder den Ausgabestream des Sockets schließt. Das Gleiche gilt natürlich auch für den Socket des Clients. Denken Sie nach Abschluss des Vorgangs daran, die entsprechenden Ressourcen zu schließen, bevor das gesamte Programm endet, dh den entsprechenden E/A-Stream und Socket.


Client-Code

Java-Code

public class Client { 
 public static void main(String args[]) throws Exception { 
 //为了简单起见,所有的异常都直接往外抛 
 String host = "127.0.0.1"; //要连接的服务端IP地址 
 int port = 8899; //要连接的服务端对应的监听端口 
 //与服务端建立连接 
 Socket client = new Socket(host, port); 
 //建立连接后就可以往服务端写数据了 
 Writer writer = new OutputStreamWriter(client.getOutputStream()); 
 writer.write("Hello Server."); 
 writer.flush();//写完后要记得flush 
 writer.close(); 
 client.close(); 
 } 
 }
Nach dem Login kopieren
Es gibt eine Sache zu beachten, wenn der Client Daten in den Ausgabestream des Sockets schreibt und an diesen weitergibt Wenn Sie schreiben, schließt das Programm nicht den Ausgabestream, sondern führt andere Blockierungsvorgänge aus (z. B. das Lesen von Daten aus dem Eingabestream). Nur auf diese Weise kann der Server empfangen werden die vom Client gesendeten Daten, andernfalls kann es dazu führen, dass beide Parteien endlos aufeinander warten. Dieses Problem wird später besprochen, wenn Client und Server gleichzeitig lesen und schreiben.


<<>

2. Der Client und der Server lesen und schreiben gleichzeitig Sockets wurden in beide Richtungen kommuniziert kann gleichzeitig Daten empfangen und senden.

Servercode


Java-Code

Im obigen Code lesen wir zuerst die vom Client gesendeten Daten aus dem Eingabestream und dann Wir Schreiben Sie dann Daten in den Ausgabestream an den Client und schließen Sie dann die entsprechende Ressourcendatei. Tatsächlich wird der obige Code möglicherweise nicht wie erwartet ausgeführt, da das Lesen von Daten aus dem Eingabestream ein blockierender Vorgang ist. Wenn die Daten in der obigen
public class Server { 
 public static void main(String args[]) throws IOException { 
 //为了简单起见,所有的异常信息都往外抛 
 int port = 8899; 
 //定义一个ServerSocket监听在端口8899上 
 ServerSocket server = new ServerSocket(port); 
 //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 
 Socket socket = server.accept(); 
 //跟客户端建立好连接之后,我们就可以获取socket的InputStream,并从中读取客户端发过来的信息了。 
 Reader reader = new InputStreamReader(socket.getInputStream()); 
 char chars[] = new char[64]; 
 int len; 
 StringBuilder sb = new StringBuilder(); 
 while ((len=reader.read(chars)) != -1) { 
  sb.append(new String(chars, 0, len)); 
 } 
 System.out.println("from client: " + sb); 
 //读完后写一句 
 Writer writer = new OutputStreamWriter(socket.getOutputStream()); 
 writer.write("Hello Client."); 
 writer.flush(); 
 writer.close(); 
 reader.close(); 
 socket.close(); 
 server.close(); 
 } 
 }
Nach dem Login kopieren
while-Schleife

gelesen werden, wird der Schleifenkörper ausgeführt, andernfalls wird er ausgeführt wird blockiert, so dass nachfolgende Schreibvorgänge nie ausgeführt werden. Die Blockierung wird erst beendet, wenn der entsprechende Socket des Clients geschlossen wird, und die While-Schleife springt ebenfalls heraus. Die Lösung für diese Situation, die möglicherweise nie ausgeführt wird, besteht darin, dass die while-Schleife bedingt herausspringen muss. Wenn man sich den obigen Code ansieht, sind die einzigen Dinge, die sich ständig ändern, die abgerufene Länge und die gelesenen Daten Es können nur noch die gelesenen Daten verwendet werden. Als Reaktion auf diese Situation einigen wir uns normalerweise auf ein End-Tag. Wenn die vom Client gesendeten Daten ein End-Tag enthalten, bedeutet dies, dass die aktuellen Daten gesendet wurden. Zu diesem Zeitpunkt können wir aus der Schleife springen. Dann sieht der verbesserte Code so aus: Java-Code

Im obigen Code liest der Server das vom Client gesendete End-Tag, also „eof“. Der Empfang der Daten wird beendet und die Schleife wird beendet, sodass der nachfolgende Code fortgesetzt werden kann.
 public class Server { 
 public static void main(String args[]) throws IOException { 
 //为了简单起见,所有的异常信息都往外抛 
 int port = 8899; 
 //定义一个ServerSocket监听在端口8899上 
 ServerSocket server = new ServerSocket(port); 
 //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 
 Socket socket = server.accept(); 
 //跟客户端建立好连接之后,我们就可以获取socket的InputStream,并从中读取客户端发过来的信息了。 
 Reader reader = new InputStreamReader(socket.getInputStream()); 
 char chars[] = new char[64]; 
 int len; 
 StringBuilder sb = new StringBuilder(); 
 String temp; 
 int index; 
 while ((len=reader.read(chars)) != -1) { 
  temp = new String(chars, 0, len); 
  if ((index = temp.indexOf("eof")) != -1) {//遇到eof时就结束接收 
  sb.append(temp.substring(0, index)); 
  break; 
  } 
  sb.append(temp); 
 } 
 System.out.println("from client: " + sb); 
 //读完后写一句 
 Writer writer = new OutputStreamWriter(socket.getOutputStream()); 
 writer.write("Hello Client."); 
 writer.flush(); 
 writer.close(); 
 reader.close(); 
 socket.close(); 
 server.close(); 
 } 
 }
Nach dem Login kopieren


Client-Code

Java-Code

public class Client { 
 
 public static void main(String args[]) throws Exception { 
 //为了简单起见,所有的异常都直接往外抛 
 String host = "127.0.0.1"; //要连接的服务端IP地址 
 int port = 8899; //要连接的服务端对应的监听端口 
 //与服务端建立连接 
 Socket client = new Socket(host, port); 
 //建立连接后就可以往服务端写数据了 
 Writer writer = new OutputStreamWriter(client.getOutputStream()); 
 writer.write("Hello Server."); 
 writer.flush(); 
 //写完以后进行读操作 
 Reader reader = new InputStreamReader(client.getInputStream()); 
 char chars[] = new char[64]; 
 int len; 
 StringBuffer sb = new StringBuffer(); 
 while ((len=reader.read(chars)) != -1) { 
  sb.append(new String(chars, 0, len)); 
 } 
 System.out.println("from server: " + sb); 
 writer.close(); 
 reader.close(); 
 client.close(); 
 } 
 }
Nach dem Login kopieren

在上述代码中我们先是给服务端发送了一段数据,之后读取服务端返回来的数据,跟之前的服务端一样在读的过程中有可能导致程序一直挂在那里,永远跳不出while循环。这段代码配合服务端的第一段代码就正好让我们分析服务端永远在那里接收数据,永远跳不出while循环,也就没有之后的服务端返回数据给客户端,客户端也就不可能接收到服务端返回的数据。解决方法如服务端第二段代码所示,在客户端发送数据完毕后,往输出流里面写入结束标记告诉服务端数据已经发送完毕了,同样服务端返回数据完毕后也发一个标记告诉客户端。那么修改后的客户端代码就应该是这个样子:

Java代码

public class Client { 
 public static void main(String args[]) throws Exception { 
 //为了简单起见,所有的异常都直接往外抛 
 String host = "127.0.0.1"; //要连接的服务端IP地址 
 int port = 8899; //要连接的服务端对应的监听端口 
 //与服务端建立连接 
 Socket client = new Socket(host, port); 
 //建立连接后就可以往服务端写数据了 
 Writer writer = new OutputStreamWriter(client.getOutputStream()); 
 writer.write("Hello Server."); 
 writer.write("eof"); 
 writer.flush(); 
 //写完以后进行读操作 
 Reader reader = new InputStreamReader(client.getInputStream()); 
 char chars[] = new char[64]; 
 int len; 
 StringBuffer sb = new StringBuffer(); 
 String temp; 
 int index; 
 while ((len=reader.read(chars)) != -1) { 
  temp = new String(chars, 0, len); 
  if ((index = temp.indexOf("eof")) != -1) { 
  sb.append(temp.substring(0, index)); 
  break; 
  } 
  sb.append(new String(chars, 0, len)); 
 } 
 System.out.println("from server: " + sb); 
 writer.close(); 
 reader.close(); 
 client.close(); 
 } 
 }
Nach dem Login kopieren

我们日常使用的比较多的都是这种客户端发送数据给服务端,服务端接收数据后再返回相应的结果给客户端这种形式。只是客户端和服务端之间不再是这种一对一的关系,而是下面要讲到的多个客户端对应同一个服务端的情况。

3、多个客户端连接同一个服务端

像前面讲的两个例子都是服务端接收一个客户端的请求之后就结束了,不能再接收其他客户端的请求了,这往往是不能满足我们的要求的。通常我们会这样做:

Java代码

public class Server { 
 public static void main(String args[]) throws IOException { 
 //为了简单起见,所有的异常信息都往外抛 
 int port = 8899; 
 //定义一个ServerSocket监听在端口8899上 
 ServerSocket server = new ServerSocket(port); 
 while (true) { 
  //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 
 Socket socket = server.accept(); 
  //跟客户端建立好连接之后,我们就可以获取socket的InputStream,并从中读取客户端发过来的信息了。 
 Reader reader = new InputStreamReader(socket.getInputStream()); 
  char chars[] = new char[64]; 
  int len; 
  StringBuilder sb = new StringBuilder(); 
  String temp; 
  int index; 
  while ((len=reader.read(chars)) != -1) { 
  temp = new String(chars, 0, len); 
  if ((index = temp.indexOf("eof")) != -1) {//遇到eof时就结束接收 
   sb.append(temp.substring(0, index)); 
   break; 
  } 
  sb.append(temp); 
  } 
  System.out.println("from client: " + sb); 
  //读完后写一句 
 Writer writer = new OutputStreamWriter(socket.getOutputStream()); 
  writer.write("Hello Client."); 
  writer.flush(); 
  writer.close(); 
  reader.close(); 
  socket.close(); 
 } 
 } 
 }
Nach dem Login kopieren

在上面代码中我们用了一个死循环,在循环体里面ServerSocket调用其accept方法试图接收来自客户端的连接请求。当没有接收到请求的时候,程序会在这里阻塞直到接收到来自客户端的连接请求,之后会跟当前建立好连接的客户端进行通信,完了后会接着执行循环体再次尝试接收新的连接请求。这样我们的ServerSocket就能接收来自所有客户端的连接请求了,并且与它们进行通信了。这就实现了一个简单的一个服务端与多个客户端进行通信的模式。

上述例子中虽然实现了一个服务端跟多个客户端进行通信,但是还存在一个问题。在上述例子中,我们的服务端处理客户端的连接请求是同步进行的,每次接收到来自客户端的连接请求后,都要先跟当前的客户端通信完之后才能再处理下一个连接请求。这在并发比较多的情况下会严重影响程序的性能,为此,我们可以把它改为如下这种异步处理与客户端通信的方式:

Java代码

public class Server { 
 public static void main(String args[]) throws IOException { 
 //为了简单起见,所有的异常信息都往外抛 
 int port = 8899; 
 //定义一个ServerSocket监听在端口8899上 
 ServerSocket server = new ServerSocket(port); 
 while (true) { 
  //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 
  Socket socket = server.accept(); 
  //每接收到一个Socket就建立一个新的线程来处理它 
  new Thread(new Task(socket)).start(); 
 } 
 } 
 /** 
 * 用来处理Socket请求的 
 */ 
 static class Task implements Runnable { 
 private Socket socket; 
 public Task(Socket socket) { 
  this.socket = socket; 
 } 
 public void run() { 
  try { 
  handleSocket(); 
  } catch (Exception e) { 
  e.printStackTrace(); 
  } 
 } 
 /** 
 * 跟客户端Socket进行通信 
 * @throws Exception 
 */ 
 private void handleSocket() throws Exception { 
  Reader reader = new InputStreamReader(socket.getInputStream()); 
  char chars[] = new char[64]; 
  int len; 
  StringBuilder sb = new StringBuilder(); 
  String temp; 
  int index; 
  while ((len=reader.read(chars)) != -1) { 
  temp = new String(chars, 0, len); 
  if ((index = temp.indexOf("eof")) != -1) {//遇到eof时就结束接收 
  sb.append(temp.substring(0, index)); 
   break; 
  } 
  sb.append(temp); 
  } 
  System.out.println("from client: " + sb); 
  //读完后写一句 
 Writer writer = new OutputStreamWriter(socket.getOutputStream()); 
  writer.write("Hello Client."); 
  writer.flush(); 
  writer.close(); 
  reader.close(); 
  socket.close(); 
 } 
 } 
 }
Nach dem Login kopieren

在上面代码中,每次ServerSocket接收到一个新的Socket连接请求后都会新起一个线程来跟当前Socket进行通信,这样就达到了异步处理与客户端Socket进行通信的情况。

在从Socket的InputStream中接收数据时,像上面那样一点点的读就太复杂了,有时候我们就会换成使用BufferedReader来一次读一行,如:

Java代码

 public class Server { 
 public static void main(String args[]) throws IOException { 
 //为了简单起见,所有的异常信息都往外抛 
 int port = 8899; 
 //定义一个ServerSocket监听在端口8899上 
 ServerSocket server = new ServerSocket(port); 
 while (true) { 
  //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 
  Socket socket = server.accept(); 
  //每接收到一个Socket就建立一个新的线程来处理它 
  new Thread(new Task(socket)).start(); 
 } 
 } 
 /** 
 * 用来处理Socket请求的 
 */ 
 static class Task implements Runnable { 
 private Socket socket; 
 public Task(Socket socket) { 
  this.socket = socket; 
 } 
 public void run() { 
  try { 
  handleSocket(); 
  } catch (Exception e) { 
  e.printStackTrace(); 
  } 
 } 
 /** 
 * 跟客户端Socket进行通信 
 * @throws Exception 
 */ 
 private void handleSocket() throws Exception { 
  BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
  StringBuilder sb = new StringBuilder(); 
  String temp; 
  int index; 
  while ((temp=br.readLine()) != null) { 
  System.out.println(temp); 
  if ((index = temp.indexOf("eof")) != -1) {//遇到eof时就结束接收 
  sb.append(temp.substring(0, index)); 
   break; 
  } 
  sb.append(temp); 
  } 
  System.out.println("from client: " + sb); 
  //读完后写一句 
 Writer writer = new OutputStreamWriter(socket.getOutputStream()); 
  writer.write("Hello Client."); 
  writer.write("eof\n"); 
  writer.flush(); 
  writer.close(); 
  br.close(); 
  socket.close(); 
 } 
 } 
 }
Nach dem Login kopieren

这个时候需要注意的是,BufferedReader的readLine方法是一次读一行的,这个方法是阻塞的,直到它读到了一行数据为止程序才会继续往下执行,那么readLine什么时候才会读到一行呢?直到程序遇到了换行符或者是对应流的结束符readLine方法才会认为读到了一行,才会结束其阻塞,让程序继续往下执行。所以我们在使用BufferedReader的readLine读取数据的时候一定要记得在对应的输出流里面一定要写入换行符(流结束之后会自动标记为结束,readLine可以识别),写入换行符之后一定记得如果输出流不是马上关闭的情况下记得flush一下,这样数据才会真正的从缓冲区里面写入。对应上面的代码我们的客户端程序应该这样写:

Java代码


 public class Client { 
 public static void main(String args[]) throws Exception { 
 //为了简单起见,所有的异常都直接往外抛 
 String host = "127.0.0.1"; //要连接的服务端IP地址 
 int port = 8899; //要连接的服务端对应的监听端口 
 //与服务端建立连接 
 Socket client = new Socket(host, port); 
 //建立连接后就可以往服务端写数据了 
 Writer writer = new OutputStreamWriter(client.getOutputStream()); 
 writer.write("Hello Server."); 
 writer.write("eof\n"); 
 writer.flush(); 
 //写完以后进行读操作 
 BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); 
 StringBuffer sb = new StringBuffer(); 
 String temp; 
 int index; 
 while ((temp=br.readLine()) != null) { 
  if ((index = temp.indexOf("eof")) != -1) { 
  sb.append(temp.substring(0, index)); 
  break; 
  } 
  sb.append(temp); 
 } 
 System.out.println("from server: " + sb); 
 writer.close(); 
 br.close(); 
 client.close(); 
 } 
 }
Nach dem Login kopieren

4、设置超时时间

假设有这样一种需求,我们的客户端需要通过Socket从服务端获取到XX信息,然后给用户展示在页面上。我们知道Socket在读数据的时候是阻塞式的,如果没有读到数据程序会一直阻塞在那里。在同步请求的时候我们肯定是不能允许这样的情况发生的,这就需要我们在请求达到一定的时间后控制阻塞的中断,让程序得以继续运行。Socket为我们提供了一个setSoTimeout()方法来设置接收数据的超时时间,单位是毫秒。当设置的超时时间大于0,并且超过了这一时间Socket还没有接收到返回的数据的话,Socket就会抛出一个SocketTimeoutException。

假设我们需要控制我们的客户端在开始读取数据10秒后还没有读到数据就中断阻塞的话我们可以这样做:

Java代码

public class Client { 
 public static void main(String args[]) throws Exception { 
 //为了简单起见,所有的异常都直接往外抛 
 String host = "127.0.0.1"; //要连接的服务端IP地址 
 int port = 8899; //要连接的服务端对应的监听端口 
 //与服务端建立连接 
 Socket client = new Socket(host, port); 
 //建立连接后就可以往服务端写数据了 
 Writer writer = new OutputStreamWriter(client.getOutputStream()); 
 writer.write("Hello Server."); 
 writer.write("eof\n"); 
 writer.flush(); 
 //写完以后进行读操作 
 BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); 
 //设置超时间为10秒 
 client.setSoTimeout(10*1000); 
 StringBuffer sb = new StringBuffer(); 
 String temp; 
 int index; 
 try { 
  while ((temp=br.readLine()) != null) { 
  if ((index = temp.indexOf("eof")) != -1) { 
   sb.append(temp.substring(0, index)); 
   break; 
  } 
  sb.append(temp); 
  } 
 } catch (SocketTimeoutException e) { 
  System.out.println("数据读取超时。"); 
 } 
 System.out.println("from server: " + sb); 
 writer.close(); 
 br.close(); 
 client.close(); 
 } 
 }
Nach dem Login kopieren

5、接收数据乱码

对于这种服务端或客户端接收中文乱码的情况通常是因为数据发送时使用的编码跟接收时候使用的编码不一致。比如有下面这样一段服务端代码:

Java代码

 public class Server { 
 public static void main(String args[]) throws IOException { 
 //为了简单起见,所有的异常信息都往外抛 
 int port = 8899; 
 //定义一个ServerSocket监听在端口8899上 
 ServerSocket server = new ServerSocket(port); 
 while (true) { 
  //server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的 
  Socket socket = server.accept(); 
  //每接收到一个Socket就建立一个新的线程来处理它 
  new Thread(new Task(socket)).start(); 
 } 
 } 
 /** 
 * 用来处理Socket请求的 
 */ 
 static class Task implements Runnable { 
 private Socket socket; 
 public Task(Socket socket) { 
  this.socket = socket; 
 } 
 public void run() { 
  try { 
  handleSocket(); 
  } catch (Exception e) { 
  e.printStackTrace(); 
  } 
 } 
 /** 
 * 跟客户端Socket进行通信 
 * @throws Exception 
 */ 
 private void handleSocket() throws Exception { 
  BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK")); 
  StringBuilder sb = new StringBuilder(); 
  String temp; 
  int index; 
  while ((temp=br.readLine()) != null) { 
  System.out.println(temp); 
  if ((index = temp.indexOf("eof")) != -1) {//遇到eof时就结束接收 
  sb.append(temp.substring(0, index)); 
   break; 
  } 
  sb.append(temp); 
  } 
  System.out.println("客户端: " + sb); 
  //读完后写一句 
 Writer writer = new OutputStreamWriter(socket.getOutputStream(), "UTF-8"); 
  writer.write("你好,客户端。"); 
  writer.write("eof\n"); 
  writer.flush(); 
  writer.close(); 
  br.close(); 
  socket.close(); 
 } 
 } 
 }
Nach dem Login kopieren

这里用来测试我就弄的混乱了一点。在上面服务端代码中我们在定义输入流的时候明确定义了使用GBK编码来读取数据,而在定义输出流的时候明确指定了将使用UTF-8编码来发送数据。如果客户端上送数据的时候不以GBK编码来发送的话服务端接收的数据就很有可能会乱码;同样如果客户端接收数据的时候不以服务端发送数据的编码,即UTF-8编码来接收数据的话也极有可能会出现数据乱码的情况。所以,对于上述服务端代码,为使我们的程序能够读取对方发送过来的数据,而不出现乱码情况,我们的客户端应该是这样的:

Java代码

public class Client { 
 public static void main(String args[]) throws Exception { 
 //为了简单起见,所有的异常都直接往外抛 
 String host = "127.0.0.1"; //要连接的服务端IP地址 
 int port = 8899; //要连接的服务端对应的监听端口 
 //与服务端建立连接 
 Socket client = new Socket(host, port); 
 //建立连接后就可以往服务端写数据了 
 Writer writer = new OutputStreamWriter(client.getOutputStream(), "GBK"); 
 writer.write("你好,服务端。"); 
 writer.write("eof\n"); 
 writer.flush(); 
 //写完以后进行读操作 
 BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8")); 
 //设置超时间为10秒 
 client.setSoTimeout(10*1000); 
 StringBuffer sb = new StringBuffer(); 
 String temp; 
 int index; 
 try { 
  while ((temp=br.readLine()) != null) { 
  if ((index = temp.indexOf("eof")) != -1) { 
   sb.append(temp.substring(0, index)); 
   break; 
  } 
  sb.append(temp); 
  } 
 } catch (SocketTimeoutException e) { 
  System.out.println("数据读取超时。"); 
 } 
 System.out.println("服务端: " + sb); 
 writer.close(); 
 br.close(); 
 client.close(); 
 } 
 }
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonEinführung in die Socket-Programmierung in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Der Schlüssel zum Programmieren: Die Leistungsfähigkeit von Python für Anfänger freischalten Der Schlüssel zum Programmieren: Die Leistungsfähigkeit von Python für Anfänger freischalten Oct 11, 2024 pm 12:17 PM

Python ist aufgrund seiner einfachen Erlernbarkeit und leistungsstarken Funktionen eine ideale Einführungssprache in die Programmierung für Anfänger. Zu seinen Grundlagen gehören: Variablen: werden zum Speichern von Daten (Zahlen, Zeichenfolgen, Listen usw.) verwendet. Datentyp: Definiert den Datentyp in der Variablen (Ganzzahl, Gleitkomma usw.). Operatoren: werden für mathematische Operationen und Vergleiche verwendet. Kontrollfluss: Kontrollieren Sie den Fluss der Codeausführung (bedingte Anweisungen, Schleifen).

Problemlösung mit Python: Erschließen Sie leistungsstarke Lösungen als Programmieranfänger Problemlösung mit Python: Erschließen Sie leistungsstarke Lösungen als Programmieranfänger Oct 11, 2024 pm 08:58 PM

Python unterstützt Anfänger bei der Problemlösung. Seine benutzerfreundliche Syntax, umfangreiche Bibliothek und Funktionen wie Variablen, bedingte Anweisungen und Schleifen ermöglichen eine effiziente Codeentwicklung. Von der Datenverwaltung über die Steuerung des Programmablaufs bis hin zur Ausführung wiederkehrender Aufgaben bietet Python

C entmystifizieren: Ein klarer und einfacher Weg für neue Programmierer C entmystifizieren: Ein klarer und einfacher Weg für neue Programmierer Oct 11, 2024 pm 10:47 PM

C ist eine ideale Wahl für Anfänger, um die Systemprogrammierung zu erlernen. Es enthält die folgenden Komponenten: Header-Dateien, Funktionen und Hauptfunktionen. Ein einfaches C-Programm, das „HelloWorld“ drucken kann, benötigt eine Header-Datei mit der Standard-Eingabe-/Ausgabe-Funktionsdeklaration und verwendet zum Drucken die printf-Funktion in der Hauptfunktion. C-Programme können mit dem GCC-Compiler kompiliert und ausgeführt werden. Nachdem Sie die Grundlagen beherrschen, können Sie mit Themen wie Datentypen, Funktionen, Arrays und Dateihandhabung fortfahren, um ein kompetenter C-Programmierer zu werden.

Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Oct 13, 2024 pm 01:32 PM

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.

Java -Programm, um das Kapselvolumen zu finden Java -Programm, um das Kapselvolumen zu finden Feb 07, 2025 am 11:37 AM

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

Entfesseln Sie Ihren inneren Programmierer: C für absolute Anfänger Entfesseln Sie Ihren inneren Programmierer: C für absolute Anfänger Oct 11, 2024 pm 03:50 PM

C ist eine ideale Sprache für Anfänger zum Erlernen des Programmierens. Zu seinen Vorteilen gehören Effizienz, Vielseitigkeit und Portabilität. Das Erlernen der C-Sprache erfordert: Installieren eines C-Compilers (z. B. MinGW oder Cygwin) Verstehen von Variablen, Datentypen, bedingten Anweisungen und Schleifenanweisungen Schreiben des ersten Programms, das die Hauptfunktion und die printf()-Funktion enthält Üben durch praktische Fälle (z. B. Berechnen von Durchschnittswerten) C-Sprachkenntnisse

Java leicht gemacht: Ein Leitfaden für Anfänger zur Programmierleistung Java leicht gemacht: Ein Leitfaden für Anfänger zur Programmierleistung Oct 11, 2024 pm 06:30 PM

Java leicht gemacht: Ein Leitfaden für Anfänger zur leistungsstarken Programmierung Java ist eine leistungsstarke Programmiersprache, die in allen Bereichen von mobilen Anwendungen bis hin zu Systemen auf Unternehmensebene verwendet wird. Für Anfänger ist die Syntax von Java einfach und leicht zu verstehen, was es zu einer idealen Wahl zum Erlernen des Programmierens macht. Grundlegende Syntax Java verwendet ein klassenbasiertes objektorientiertes Programmierparadigma. Klassen sind Vorlagen, die zusammengehörige Daten und Verhaltensweisen organisieren. Hier ist ein einfaches Java-Klassenbeispiel: publicclassPerson{privateStringname;privateintage;

See all articles