传输层协议:
TCP和UDP的区别:
TCP:面向连接(经历三次握手)、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。 服务端和客户端
UDP:面向非连接、传输不可靠(丢包[数据丢失])、用于传输少量数据(数据报包模式)、速度快。发送端和接收端
java中TCP传输实现:
中文API解释:
类 Socket
java.lang.Objectjava.net.Socket
- 直接已知子类:
- SSLSocket
public class Socketextends Object
此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。
套接字的实际工作由 SocketImpl
类的实例执行。应用程序通过更改创建套接字实现的套接字工厂可以配置它自身,以创建适合本地防火墙的套接字。
构造方法摘要 | |
---|---|
| Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 |
| Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 |
| Socket(InetAddress host, int port, boolean stream) 已过时。 Use DatagramSocket instead for UDP transport. |
| Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 创建一个套接字并将其连接到指定远程地址上的指定远程端口。 |
| Socket(Proxy proxy) 创建一个未连接的套接字并指定代理类型(如果有),该代理不管其他设置如何都应被使用。 |
protected | Socket(SocketImpl impl) 使用用户指定的 SocketImpl 创建一个未连接 Socket。 |
| Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。 |
| Socket(String host, int port, boolean stream) 已过时。 使用 DatagramSocket 取代 UDP 传输。 |
| Socket(String host, int port, InetAddress localAddr, int localPort) 创建一个套接字并将其连接到指定远程主机上的指定远程端口。 |
java.net 类 ServerSocket
java.lang.Objectjava.net.ServerSocket
- 直接已知子类:
- SSLServerSocket
public class ServerSocketextends Object
此类实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
服务器套接字的实际工作由 SocketImpl
类的实例执行。应用程序可以更改创建套接字实现的套接字工厂来配置它自身,从而创建适合本地防火墙的套接字。
- 从以下版本开始:
- JDK1.0 另请参见:
SocketImpl
,setSocketFactory(java.net.SocketImplFactory)
,ServerSocketChannel
构造方法摘要 | |
---|---|
ServerSocket() 创建非绑定服务器套接字。 | |
ServerSocket(int port) 创建绑定到特定端口的服务器套接字。 | |
ServerSocket(int port, int backlog) 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。 | |
ServerSocket(int port, int backlog, InetAddress bindAddr) 使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。 |
package netCode;import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;public class TCPClient {public static void main(String[] args) throws UnknownHostException, IOException {System.out.println("------------我是客户端---------------");//创建客户端对象连接服务器端的主机和端口,第一个参数为服务器的IP地址,第二个为占用的端口号Socket client = new Socket("localhost", 10086);//获取客户端输入流的对象//为了避免中文乱码的问题转换成UTF-8格式Scanner sc = new Scanner(client.getInputStream(),"UTF-8");while(sc.hasNext()){System.out.println(sc.nextLine().getBytes());}sc.close();client.close();}
}
package netCode;import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;public class TCPServer {public static void main(String[] args) throws UnknownHostException, IOException {String data = "魏杰";System.out.println("-----------服务器端----------------");ServerSocket server = new ServerSocket(10088);System.out.println("服务器已经准备就绪");while(true){//接受连接服务器的客户端对象Socket client = server.accept();System.out.println("连接过来的客户端:"+client.getPort()+"-"+client.getLocalAddress()+"-"+client.getInetAddress());System.out.println("客户端数据:"+data);//获取服务器输出流的对象//为了避免中文乱码的问题转换成UTF-8格式PrintStream out = new PrintStream(client.getOutputStream(),false, "UTF-8");out.print(data);out.close();}}
}
注意:运行时候首先运行服务器端的,然后再运行客户端,再观察客户端控制台中输出内容。
java中UDP传输实现:
中文API解释:
java.net
类 DatagramSocket
java.lang.Objectjava.net.DatagramSocket
- 直接已知子类:
- MulticastSocket
public class DatagramSocketextends Object
此类表示用来发送和接收数据报包的套接字。
数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。
在 DatagramSocket 上总是启用 UDP 广播发送。为了接收广播包,应该将 DatagramSocket 绑定到通配符地址。在某些实现中,将 DatagramSocket 绑定到一个更加具体的地址时广播包也可以被接收。
示例:DatagramSocket s = new DatagramSocket(null); s.bind(new InetSocketAddress(8888));
这等价于:DatagramSocket s = new DatagramSocket(8888);
两个例子都能创建能够在 UDP 8888 端口上接收广播的 DatagramSocket。
构造方法摘要 | |
---|---|
| DatagramSocket() 构造数据报套接字并将其绑定到本地主机上任何可用的端口。 |
protected | DatagramSocket(DatagramSocketImpl impl) 创建带有指定 DatagramSocketImpl 的未绑定数据报套接字。 |
| DatagramSocket(int port) 创建数据报套接字并将其绑定到本地主机上的指定端口。 |
| DatagramSocket(int port, InetAddress laddr) 创建数据报套接字,将其绑定到指定的本地地址。 |
| DatagramSocket(SocketAddress bindaddr) 创建数据报套接字,将其绑定到指定的本地套接字地址。 |
java.net 类 DatagramPacket
java.lang.Objectjava.net.DatagramPacket
public final class DatagramPacketextends Object
此类表示数据报包。
数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。
构造方法摘要 | |
---|---|
DatagramPacket(byte[] buf, int length) 构造 DatagramPacket ,用来接收长度为 length 的数据包。 | |
DatagramPacket(byte[] buf, int length, InetAddress address, int port) 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。 | |
DatagramPacket(byte[] buf, int offset, int length) 构造 DatagramPacket ,用来接收长度为 length 的包,在缓冲区中指定了偏移量。 | |
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。 | |
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 构造数据报包,用来将长度为 length 偏移量为 offset 的包发送到指定主机上的指定端口号。 | |
DatagramPacket(byte[] buf, int length, SocketAddress address) 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。 |
package netCode;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 UDPSend {public static void main(String[] args) throws Exception {System.out.println("----------我是发送端-----------------");//发送的数据String data = "大数据开发工程师";//创建发送端对象DatagramSocket send = new DatagramSocket(10010); //发送数据DatagramPacket packet = new DatagramPacket(data.getBytes(), data.getBytes().length,InetAddress.getLocalHost(),10086);send.send(packet);send.close();}
}
package netCode;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UDPReceived {public static void main(String[] args) throws Exception {System.out.println("-----------我是接收端----------------");//创建连接对象DatagramSocket receive = new DatagramSocket(10086);//接受数据byte[] b = new byte[1024];DatagramPacket packet = new DatagramPacket(b,1024);receive.receive(packet);//获取接受的数据String str = new String(packet.getData(),0,packet.getLength());System.out.println(str);}
}
注意:UDP发送端和接受端不能为同一个端口号否则会报错显示端口已经被占用的异常,先运行接收端然后运行发送端可以看到控制台输出内容