首页 > 代码库 > Java网络编程之TCP、UDP
Java网络编程之TCP、UDP
Java网络编程提供了两种协议:TCP(传输控制协议)和UDP(数据报协议)。TCP(Transmission Control Protocol)是一种可靠的传输协议,传输时会采用“三次握手”端的方式建立连接,以保证数据的可靠性和安全性;而UDP(User Datagram Protocol)协议是一种不可靠的传输协议,发送的数据不一定能够接受的到,网上的聊天是工具一般采用的此协议。下面将详细的接受TCP和UDP的使用以及相应的编码。
一、TCP网络通信
Java中使用Socket(套接字)实现TCP。服务器端使用ServerSocket类,客户端使用Socket类实现。
1、ServerSocket类
其主要有如下的方法:
一、TCP网络通信
Java中使用Socket(套接字)实现TCP。服务器端使用ServerSocket类,客户端使用Socket类实现。
1、ServerSocket类
其主要有如下的方法:
ServerSocket() 创建非绑定服务器套接字。
ServerSocket(int port) 创建绑定到特定端口的服务器套接字。
Socket accept() 侦听并接受到此套接字的连接。
void close() 关闭此套接字
boolean isClosed() 返回 ServerSocket 的关闭状态。
InetAddress getInetAddress() 返回此服务器套接字的本地地址。
void bind(SocketAddress endpoint) 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
boolean isBound() 返回 ServerSocket 的绑定状态。
SocketAddress getLocalSocketAddress() 返回此套接字绑定的端点的地址,如果尚未绑定则返回 null。
服务器端每次运行是都要使用accept()方法等待客户端的连接,此方法执行之后服务器端将进入阻塞状态,知道客户端连接之后程序才继续执行,此方法返回是Socket,代表一个客户端对象。
2、Socket类
两台机器连接通信的端点。主要使用如下方法:
Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。
OutputStream getOutputStream() 返回此套接字的输出流。
InputStream getInputStream() 返回此套接字的输入流。
boolean isBound() 返回套接字的绑定状态。
boolean isClosed() 返回套接字的关闭状态。
boolean isConnected() 返回套接字的连接状态。
void close() 关闭此套接字。
其通过字节流和服务端进行通信。
实例一、下面是实现一个简单的TCP客户端可服务器端通信。
(1)服务器端:
(2)客户端:
实例二
实现客户端和服务器端的通信,服务器端可以响应多个客户端,每个客户端请求就启动一个线程。
(1)服务端
对应服务端线程任务:
(2)客户端
二、UDP网络通信
TCP的通信是建立在可靠通信的基础上,UDP则是不可靠的通信,使用数据报形式发送数据。
在Java中主要有DatagramPacket和DatagramSocket实现。
1、DatagramPacket主要方法
DatagramPacket(byte[] buf, int length)
构造 DatagramPacket,用来接收长度为 length 的数据包。
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
byte[] getData()
返回数据缓冲区。
int getLength()
返回将要发送或接收到的数据的长度。
2、DatagramSocket主要方法
DatagramSocket(int port)
创建数据报套接字并将其绑定到本地主机上的指定端口。
void receive(DatagramPacket p)
从此套接字接收数据报包。
void send(DatagramPacket p)
从此套接字发送数据报包。
在使用UDP时,先使用客户端指定好要接受的数据和端口。然后开启服务端发送数据。
实现如下:
(1)客户端
(2)服务器端
ServerSocket(int port) 创建绑定到特定端口的服务器套接字。
Socket accept() 侦听并接受到此套接字的连接。
void close() 关闭此套接字
boolean isClosed() 返回 ServerSocket 的关闭状态。
InetAddress getInetAddress() 返回此服务器套接字的本地地址。
void bind(SocketAddress endpoint) 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。
boolean isBound() 返回 ServerSocket 的绑定状态。
SocketAddress getLocalSocketAddress() 返回此套接字绑定的端点的地址,如果尚未绑定则返回 null。
服务器端每次运行是都要使用accept()方法等待客户端的连接,此方法执行之后服务器端将进入阻塞状态,知道客户端连接之后程序才继续执行,此方法返回是Socket,代表一个客户端对象。
2、Socket类
两台机器连接通信的端点。主要使用如下方法:
Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。
OutputStream getOutputStream() 返回此套接字的输出流。
InputStream getInputStream() 返回此套接字的输入流。
boolean isBound() 返回套接字的绑定状态。
boolean isClosed() 返回套接字的关闭状态。
boolean isConnected() 返回套接字的连接状态。
void close() 关闭此套接字。
其通过字节流和服务端进行通信。
实例一、下面是实现一个简单的TCP客户端可服务器端通信。
(1)服务器端:
package andy.network.test; import java.io.IOException; import java.io.PrintStream; import java.net.ServerSocket; import java.net.Socket; /** * @author Zhang,Tianyou * version:2014-11-25 上午10:49:11 * * */ public class FirstTCPServer { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { //创建服务器 ServerSocket server = null; Socket socket = null; PrintStream out = null; //服务器在9999上等待客户端的访问 server = new ServerSocket(9999); System.out.println("服务器端已经运行,等待客户的响应。。。"); //程序阻塞 等待客户端的访问 socket = server.accept(); //向客户端输出信息 String str = "hello andy."; out = new PrintStream(socket.getOutputStream()); out.print(str); out.close(); socket.close(); server.close(); } }
(2)客户端:
package andy.network.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import java.net.UnknownHostException; /** * @author Zhang,Tianyou * version:2014-11-25 上午11:02:17 * * */ public class FirstTCPSocket { /** * @param args * @throws IOException * @throws UnknownHostException */ public static void main(String[] args) throws UnknownHostException, IOException { // 定义客户端 Socket client = null; // 设置地址和端口 client = new Socket("localhost", 9999); BufferedReader buf = null; // 结束服务端流 buf = new BufferedReader(new InputStreamReader(client.getInputStream())); String str = buf.readLine(); System.out.println("服务器端通知信息:" + str); buf.close(); client.close(); } }
实例二
实现客户端和服务器端的通信,服务器端可以响应多个客户端,每个客户端请求就启动一个线程。
(1)服务端
package andy.network.test; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * @author Zhang,Tianyou * version:2014-11-25 上午11:41:22 * * 聊天服务器端 */ public class ChatServer { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { ServerSocket server = null; Socket client = null; // 监听9999端口的连接 server = new ServerSocket(9999); boolean flag = true; while (flag) { System.out.println("服务器运行,等待客户端连接。"); client = server.accept(); // 对每一个客户端请求启动一个线程 new Thread(new ChatThread(client)).start(); } server.close(); } }
对应服务端线程任务:
package andy.network.test; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; /** * @author Zhang,Tianyou * version:2014-11-25 上午11:24:26 * * 使用多线程机制,在每个用户响应之后启动一个新任务 * */ public class ChatThread implements Runnable { // 接受客户端 private Socket client = null; public ChatThread(Socket client) { this.client = client; } @Override public void run() { // 向客户端发送数据 PrintStream out = null; // 接收客户端发来的数据 BufferedReader buff = null; try { // 得到客户端的输入信息 buff = new BufferedReader(new InputStreamReader( client.getInputStream())); out = new PrintStream(client.getOutputStream()); //标志是否一个客户端的操作完毕 boolean flag = true; while (flag) { //不断的接收信息 String str = buff.readLine(); if(str == null || "".equals(str)){ flag = false;//客户端操作结束 }else{ if("bye".equals(str)){ flag = false; out.println("bye-bye"); }else { //向客户端回显输入 out.println("you input:" + str); } } } out.close(); client.close(); } catch (Exception e) { System.out.println("服务器异常!"); } } }
(2)客户端
package andy.network.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintStream; import java.net.Socket; import java.net.UnknownHostException; /** * @author Zhang,Tianyou * version:2014-11-25 上午11:53:03 * * 聊天客户端程序 * */ public class ChatClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket client = null; client = new Socket("localhost", 9999); // 接收服务器端的信息 BufferedReader buff = null; // 向服务器端发送数据 PrintStream out = null; BufferedReader input = null; // 获取键盘输入数据 input = new BufferedReader(new InputStreamReader(System.in)); out = new PrintStream(client.getOutputStream()); buff = new BufferedReader( new InputStreamReader(client.getInputStream())); // 标志位 boolean flag = true; while (flag) { System.out.println("输入信息:"); String str = input.readLine(); // 向服务器端输出信息 out.println(str); if ("bye".equals(str)) { flag = false; } else { String chatCont = buff.readLine(); System.out.println(chatCont); } } client.close(); buff.close(); } }
二、UDP网络通信
TCP的通信是建立在可靠通信的基础上,UDP则是不可靠的通信,使用数据报形式发送数据。
在Java中主要有DatagramPacket和DatagramSocket实现。
1、DatagramPacket主要方法
DatagramPacket(byte[] buf, int length)
构造 DatagramPacket,用来接收长度为 length 的数据包。
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
byte[] getData()
返回数据缓冲区。
int getLength()
返回将要发送或接收到的数据的长度。
2、DatagramSocket主要方法
DatagramSocket(int port)
创建数据报套接字并将其绑定到本地主机上的指定端口。
void receive(DatagramPacket p)
从此套接字接收数据报包。
void send(DatagramPacket p)
从此套接字发送数据报包。
在使用UDP时,先使用客户端指定好要接受的数据和端口。然后开启服务端发送数据。
实现如下:
(1)客户端
package andy.network.test; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * @author Zhang,Tianyou * version:2014-11-25 下午3:04:10 * * UDP客户端 */ public class UDPClient { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // 客户在9999端口监听 DatagramSocket dSocket = null; dSocket = new DatagramSocket(9999); // 定义接收数据的字节长度 byte[] buff = new byte[1024]; DatagramPacket dPacket = null; // 指定接收数据的长度1024 dPacket = new DatagramPacket(buff, 1024); System.out.println("等待接受数据。。"); //接收数据 dSocket.receive(dPacket); String str = new String(dPacket.getData(), 0, dPacket.getLength()) + "from" + dPacket.getAddress().getHostAddress() + ":" + dPacket.getPort(); System.out.println(str); //关闭数据报套接字 dSocket.close(); } }
(2)服务器端
package andy.network.test; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; /** * @author Zhang,Tianyou * version:2014-11-25 下午3:13:38 * * UDP服务器端 * */ public class UDPServer { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { DatagramSocket dSocket = null; //服务端在3333端口监听 dSocket = new DatagramSocket(3333); DatagramPacket dPacket = null; //要发生的数据 String str = "hello andy!"; //向目标端口地址发送数据报 dPacket = new DatagramPacket(str.getBytes(), str.length(), InetAddress.getByName("localhost") , 9999); System.out.println("发送数据报"); dSocket.send(dPacket); dSocket.close(); } }
Java网络编程之TCP、UDP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。