### 基于TCP协议的网络编程 TCP 是面向连接的运输层协议,比较复杂,应用程序在使用 TCP 协议之前必须先建立连接,才能传输数据,数据传输完毕之后需要释放已经建立的连接。 TCP 的优点是非常可靠,通过 TCP 传输的数据,不会出现数据丢失的情况,并且数据是按照先后顺序依次到达的,缺点是速度慢,效率低。 ```java import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) { ServerSocket serverSocket = null; Socket socket = null; OutputStream outputStream = null; InputStream inputStream = null; DataInputStream dataInputStream = null; DataOutputStream dataOutputStream = null; try { //创建服务端对象 serverSocket = new ServerSocket(8080); System.out.println("------服务端------"); System.out.println("已启动,等待接收客户端请求..."); while(true) { //接收到了一个客户端对象 socket = serverSocket.accept(); inputStream = socket.getInputStream(); dataInputStream = new DataInputStream(inputStream); String request = dataInputStream.readUTF(); System.out.println("接收到了客户端请求:"+request); //给客户端作出响应 String response = "Hello World"; System.out.println("给客户端作出的响应:"+response); outputStream = socket.getOutputStream(); dataOutputStream = new DataOutputStream(outputStream); dataOutputStream.writeUTF(response); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataOutputStream.close(); dataInputStream.close(); outputStream.close(); inputStream.close(); socket.close(); serverSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ``` ```java import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] args) { Socket socket = null; OutputStream outputStream = null; DataOutputStream dataOutputStream = null; InputStream inputStream = null; DataInputStream dataInputStream = null; try { socket = new Socket("127.0.0.1",8080); System.out.println("------客户端------"); String request = "你好!"; System.out.println("客户端说:"+request); outputStream = socket.getOutputStream(); dataOutputStream = new DataOutputStream(outputStream); dataOutputStream.writeUTF(request); //接收客户端的响应 inputStream = socket.getInputStream(); dataInputStream = new DataInputStream(inputStream); String response = dataInputStream.readUTF(); System.out.println("服务端响应:"+response); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataInputStream.close(); inputStream.close(); dataOutputStream.close(); outputStream.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ``` ### 基于UDP协议的网络编程 UDP 所有的连接都是不可靠的,即不需要建立连接,直接发送数据。 UDP 的速度更快,但是可能会造成数据丢失,安全性不高,追求速度的应用可以选择 UDP。 TerminalA ```java import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketAddress; import java.net.SocketException; public class TerminalA { public static void main(String[] args) { try { //接收数据 byte[] buff = new byte[1024]; DatagramPacket datagramPacket = new DatagramPacket(buff, buff.length); DatagramSocket datagramSocket = new DatagramSocket(8181); datagramSocket.receive(datagramPacket); String message = new String(datagramPacket.getData(),0,datagramPacket.getLength()); System.out.println("我是TerminalA,接收到了"+datagramPacket.getPort()+"传来的数据:"+message); //发送数据 String reply = "我是TerminalA,已经接收到你发来的消息"; SocketAddress socketAddress = datagramPacket.getSocketAddress(); DatagramPacket datagramPacket2 = new DatagramPacket(reply.getBytes(),reply.getBytes().length,socketAddress); datagramSocket.send(datagramPacket2); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ``` TerminalB ```java 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 TerminalB { public static void main(String[] args) { try { //发送数据 String message = "我是TerminalB,你好!"; InetAddress inetAddress = InetAddress.getByName("localhost"); DatagramPacket datagramPacket = new DatagramPacket(message.getBytes(), message.getBytes().length,inetAddress,8181); DatagramSocket datagramSocket = new DatagramSocket(8080); datagramSocket.send(datagramPacket); //接收数据 byte[] buff = new byte[1024]; DatagramPacket datagramPacket2 = new DatagramPacket(buff, buff.length); datagramSocket.receive(datagramPacket2); String reply = new String(datagramPacket2.getData(),0,datagramPacket2.getLength()); System.out.println("我是TerminalB,接收到了"+datagramPacket2.getPort()+"返回的数据:"+reply); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ``` ### 多线程下的网络编程 上述代码都是基于单点连接的方式,即一个服务端对应一个客户端,实际运行环境中一个服务端需要对应多个客户端的,这种情况可以通过多线程来模拟。 ServerRunnable ```java import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class ServerRunnable implements Runnable { private Socket socket; public ServerRunnable(Socket socket) { // TODO Auto-generated constructor stub this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub InputStream inputStream = null; DataInputStream dataInputStream = null; try { inputStream = this.socket.getInputStream(); dataInputStream = new DataInputStream(inputStream); String message = dataInputStream.readUTF(); System.out.println(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataInputStream.close(); inputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ``` ServerThread ```java import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class ServerThread { public static void main(String[] args) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(8080); System.out.println("服务器已启动......"); while(true) { Socket socket = serverSocket.accept(); ServerRunnable serverRunnable = new ServerRunnable(socket); Thread thred = new Thread(serverRunnable); thred.start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ``` ClientRunnable ```java import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class ClientRunnable implements Runnable { private int num; public ClientRunnable(int num) { // TODO Auto-generated constructor stub this.num = num; } @Override public void run() { // TODO Auto-generated method stub Socket socket = null; OutputStream outputStream = null; DataOutputStream dataOutputStream = null; try { socket = new Socket("localhost", 8080); String mess = "我是客户端"+this.num; outputStream = socket.getOutputStream(); dataOutputStream = new DataOutputStream(outputStream); dataOutputStream.writeUTF(mess); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataOutputStream.close(); outputStream.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ``` ClientThread ```java public class ClientThread { public static void main(String[] args) { for(int i = 0;i<100;i++) { ClientRunnable clientRunnable = new ClientRunnable(i); Thread thread = new Thread(clientRunnable); thread.start(); } } } ``` MyServerThread ```java import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class MyServerThread extends Thread { private Socket socket; public MyServerThread(Socket socket) { // TODO Auto-generated constructor stub this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub InputStream inputStream = null; DataInputStream dataInputStream = null; try { inputStream = this.socket.getInputStream(); dataInputStream = new DataInputStream(inputStream); String message = dataInputStream.readUTF(); System.out.println(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataInputStream.close(); inputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ``` ServerThread2 ```java import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class ServerThread2 { public static void main(String[] args) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(9090); System.out.println("------服务器启动------"); while(true) { Socket socket = serverSocket.accept(); MyServerThread myServerThread = new MyServerThread(socket); myServerThread.start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } ``` MyClientThread ```java import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class MyClientThread extends Thread { private int num; public MyClientThread(int num) { // TODO Auto-generated constructor stub this.num = num; } @Override public void run() { // TODO Auto-generated method stub Socket socket = null; OutputStream outputStream = null; DataOutputStream dataOutputStream = null; try { socket = new Socket("localhost", 9090); String mess = "我是客户端"+this.num; outputStream = socket.getOutputStream(); dataOutputStream = new DataOutputStream(outputStream); dataOutputStream.writeUTF(mess); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataOutputStream.close(); outputStream.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } ``` ClientThread2 ```java public class ClientThread2 { public static void main(String[] args) { for(int i=0;i<100;i++) { MyClientThread myClientThread = new MyClientThread(i); myClientThread.start(); } } } ```
Client.java
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] args) { Socket socket = null; OutputStream outputStream = null; DataOutputStream dataOutputStream = null; InputStream inputStream = null; DataInputStream dataInputStream = null; try { socket = new Socket("127.0.0.1",8080); System.out.println("------客户端------"); String request = "你好!"; System.out.println("客户端说:"+request); outputStream = socket.getOutputStream(); dataOutputStream = new DataOutputStream(outputStream); dataOutputStream.writeUTF(request); //接收客户端的响应 inputStream = socket.getInputStream(); dataInputStream = new DataInputStream(inputStream); String response = dataInputStream.readUTF(); System.out.println("服务端响应:"+response); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataInputStream.close(); inputStream.close(); dataOutputStream.close(); outputStream.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
ClientRunnable.java
import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class ClientRunnable implements Runnable { private int num; public ClientRunnable(int num) { // TODO Auto-generated constructor stub this.num = num; } @Override public void run() { // TODO Auto-generated method stub Socket socket = null; OutputStream outputStream = null; DataOutputStream dataOutputStream = null; try { socket = new Socket("localhost", 8080); String mess = "我是客户端"+this.num; outputStream = socket.getOutputStream(); dataOutputStream = new DataOutputStream(outputStream); dataOutputStream.writeUTF(mess); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataOutputStream.close(); outputStream.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
ClientThread.java
public class ClientThread { public static void main(String[] args) { for(int i = 0;i<100;i++) { ClientRunnable clientRunnable = new ClientRunnable(i); Thread thread = new Thread(clientRunnable); thread.start(); } } }
ClentThread2.java
public class ClientThread2 { public static void main(String[] args) { for(int i=0;i<100;i++) { MyClientThread myClientThread = new MyClientThread(i); myClientThread.start(); } } }
MyClentThread.java
import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; public class MyClientThread extends Thread { private int num; public MyClientThread(int num) { // TODO Auto-generated constructor stub this.num = num; } @Override public void run() { // TODO Auto-generated method stub Socket socket = null; OutputStream outputStream = null; DataOutputStream dataOutputStream = null; try { socket = new Socket("localhost", 9090); String mess = "我是客户端"+this.num; outputStream = socket.getOutputStream(); dataOutputStream = new DataOutputStream(outputStream); dataOutputStream.writeUTF(mess); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataOutputStream.close(); outputStream.close(); socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
MyServerThread.java
import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class MyServerThread extends Thread { private Socket socket; public MyServerThread(Socket socket) { // TODO Auto-generated constructor stub this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub InputStream inputStream = null; DataInputStream dataInputStream = null; try { inputStream = this.socket.getInputStream(); dataInputStream = new DataInputStream(inputStream); String message = dataInputStream.readUTF(); System.out.println(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataInputStream.close(); inputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
Server.java
import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) { ServerSocket serverSocket = null; Socket socket = null; OutputStream outputStream = null; InputStream inputStream = null; DataInputStream dataInputStream = null; DataOutputStream dataOutputStream = null; try { //创建服务端对象 serverSocket = new ServerSocket(8080); System.out.println("------服务端------"); System.out.println("已启动,等待接收客户端请求..."); while(true) { //接收到了一个客户端对象 socket = serverSocket.accept(); inputStream = socket.getInputStream(); dataInputStream = new DataInputStream(inputStream); String request = dataInputStream.readUTF(); System.out.println("接收到了客户端请求:"+request); //给客户端作出响应 String response = "Hello World"; System.out.println("给客户端作出的响应:"+response); outputStream = socket.getOutputStream(); dataOutputStream = new DataOutputStream(outputStream); dataOutputStream.writeUTF(response); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataOutputStream.close(); dataInputStream.close(); outputStream.close(); inputStream.close(); socket.close(); serverSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
ServerRunnable.java
import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class ServerRunnable implements Runnable { private Socket socket; public ServerRunnable(Socket socket) { // TODO Auto-generated constructor stub this.socket = socket; } @Override public void run() { // TODO Auto-generated method stub InputStream inputStream = null; DataInputStream dataInputStream = null; try { inputStream = this.socket.getInputStream(); dataInputStream = new DataInputStream(inputStream); String message = dataInputStream.readUTF(); System.out.println(message); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { dataInputStream.close(); inputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
ServerThread.java
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class ServerThread { public static void main(String[] args) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(8080); System.out.println("服务器已启动......"); while(true) { Socket socket = serverSocket.accept(); ServerRunnable serverRunnable = new ServerRunnable(socket); Thread thred = new Thread(serverRunnable); thred.start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
ServerThread2.java
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class ServerThread2 { public static void main(String[] args) { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(9090); System.out.println("------服务器启动------"); while(true) { Socket socket = serverSocket.accept(); MyServerThread myServerThread = new MyServerThread(socket); myServerThread.start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
TerminalA.java
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketAddress; import java.net.SocketException; public class TerminalA { public static void main(String[] args) { try { //接收数据 byte[] buff = new byte[1024]; DatagramPacket datagramPacket = new DatagramPacket(buff, buff.length); //TerminaA的端口8181 DatagramSocket datagramSocket = new DatagramSocket(8181); datagramSocket.receive(datagramPacket); String message = new String(datagramPacket.getData(),0,datagramPacket.getLength()); System.out.println("我是TerminalA,接收到了"+datagramPacket.getPort()+"传来的数据:"+message); //发送数据 String reply = "我是TerminalA,已经接收到你发来的消息"; SocketAddress socketAddress = datagramPacket.getSocketAddress(); DatagramPacket datagramPacket2 = new DatagramPacket(reply.getBytes(),reply.getBytes().length,socketAddress); datagramSocket.send(datagramPacket2); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
TerminalB.java
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 TerminalB { public static void main(String[] args) { try { //发送数据 String message = "我是TerminalB,你好!"; InetAddress inetAddress = InetAddress.getByName("localhost"); DatagramPacket datagramPacket = new DatagramPacket(message.getBytes(), message.getBytes().length,inetAddress,8181); //TerminalB的端口8080 DatagramSocket datagramSocket = new DatagramSocket(8080); datagramSocket.send(datagramPacket); //接收数据 byte[] buff = new byte[1024]; DatagramPacket datagramPacket2 = new DatagramPacket(buff, buff.length); datagramSocket.receive(datagramPacket2); String reply = new String(datagramPacket2.getData(),0,datagramPacket2.getLength()); System.out.println("我是TerminalB,接收到了"+datagramPacket2.getPort()+"返回的数据:"+reply); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SocketException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }