一:InetAddress:
该类用于封装一个ip地址。
二:UDP通信:
1.UDP通信的特点:
UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输协议,它在网络中实现了简单的数据传输。与TCP(Transmission Control Protocol,传输控制协议)不同,UDP不提供数据的可靠性和流量控制机制。UDP通信是一种一对一或一对多的通信方式,数据通过数据报(Datagram)的形式在网络上进行传输。
UDP通信具有以下特点:
1. 无连接:UDP通信不需要在通信前建立连接,也不需要维护连接状态。
2. 不可靠:UDP通信发送的数据报无法保证可靠性,数据可能会丢失或乱序。
3. 快速:UDP通信没有TCP中建立连接和断开连接的过程,因此通信速度较快。
4. 简单:UDP通信协议较为简单,没有复杂的流量控制和错误恢复机制。
UDP通信适用于一些对数据传输的实时性要求较高,但对数据可靠性要求相对较低的场景,例如音频、视频流传输、在线游戏等。由于UDP通信的快速性和简单性,它在某些场景下也可以用于一些短消息的传输。
2.客户端创建步骤:
1.创建DatagramSocket对象;
2.创建DatagramPacket数据对象封装;
3.发送DatagramPacket数据包;
3.服务端创建步骤:
1.创建DatabramSocket对象;
2.创建DatagramPacket对象;
3.接受并输出数据;
4.Datagramsocket:
(1).构造方法:
常见的构造方法有两种,一种是不带参数的,一种是以端口号为参数的。一般客户端创建DatagramSocket对象使用无参的构造方法,而服务端则使用有参的构造方法。
(2).常用方法:
5.DatagramPacket:
(1).构造方法:
常用的构造方法为前两种,客户端常用第二种构造方法,服务端常用第一种构造方法 。
(2).常用方法:
6.数据包的创建:
Scanner s=new Scanner(System.in);
String string=s.nextLine();
byte[] buffer=string.getBytes();
DatagramPacket packet=new DatagramPacket(buffer,buffer.length,InetAddress.getLocalHost(),6666);//客户端
byte[] buffer=new byte[1024*64];//接收数据的最大值
DatagramPacket packet=new DatagramPacket(bufffer,buffer.length);//服务端
7.完整代码:
(1).客户端:
package 网络通信1;
/*1.创建服务员
*2.创建盘子发送韭菜
*3.撤走服务员
*/
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws Exception
{
Scanner sc=new Scanner(System.in);
String ss=sc.nextLine();
//1.创建客户端对象
DatagramSocket socket=new DatagramSocket();
//2. 创建数据包对象封装
/* public DatagramPacket(byte buf[], int length,
InetAddress address, int port)
1.第一个参数:封装要发出去的数据
2.第二个参数:发出去数据的大小
3.第三个参数:服务端的IP地址
4.第四个参数:服务端程序的端口
*/
byte[] buffer=ss.getBytes();
DatagramPacket packet=new DatagramPacket(buffer,buffer.length,
InetAddress.getLocalHost(),6666);
//3.发数据包
socket.send(packet);
System.out.println("客户端数据发送成功~~~");
socket.close();//释放资源
}
}
(2).服务端:
package 网络通信1;
/*1.创建服务员
*2.创建盘子接受韭菜
*3.撤走服务员
*/
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Server {
public static void main(String[] args) throws Exception
{
System.out.println("-------服务端启动成功-------");
//1.创建服务端程序的端口对象
DatagramSocket socket=new DatagramSocket(6666);
//2.创建接收数据包对象
byte[] buffer=new byte[1024*64];
DatagramPacket packet=new DatagramPacket(buffer,buffer.length);
socket.receive(packet);
int len=packet.getLength();
System.out.println(new String(buffer,0,len));
socket.close();
}
}
运行时,须先运行服务端,后运行客户端。
三:TCP通信:
1.TCP通信的特点:
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它是互联网协议套件(TCP/IP)的核心协议之一,主要用于在IP网络中提供数据传输服务。以下是TCP通信的一些基本概念:
1. **面向连接**:TCP在传输数据之前需要建立一个连接,这称为三次握手过程。一旦连接建立,数据就可以在两个端点之间传输,直到连接被关闭。
2. **数据传输**:TCP通过字节流的形式传输数据,这意味着数据被看作是一个连续的字节序列,而不是消息或数据包。
3. **可靠性**:TCP确保数据可靠地从发送端传输到接收端。它通过序列号、确认应答、重传机制等来实现这一点。
4. **流量控制**:TCP使用滑动窗口机制来控制数据的发送速率,以避免接收端被过多的数据淹没。
5. **拥塞控制**:TCP还具有拥塞控制机制,当网络出现拥塞时,它可以减少数据的发送速率,以减轻网络的负担。
6. **三次握手**:建立TCP连接的过程,包括SYN(同步序列编号)、ACK(确认应答)等步骤。
7. **四次挥手**:关闭TCP连接的过程,包括FIN(结束)、ACK等步骤。
8. **端口号**:TCP使用端口号来区分不同的服务或进程,每个TCP连接由一个四元组(源IP地址、源端口号、目的IP地址、目的端口号)唯一标识。
9. **TCP报文**:TCP数据传输的基本单位,包含源端口、目的端口、序列号、确认号、数据偏移量、控制位(如SYN、ACK、FIN等)和其他可选字段。
10. **超时和重传**:如果发送的数据没有在预定时间内收到确认,TCP会进行超时并重传数据。
TCP协议广泛应用于各种网络应用中,如Web浏览(HTTP)、文件传输(FTP)、电子邮件(SMTP)等。
2.客户端创建步骤:
1.创建socket对象,用来接通通道;
2.向服务端发送数据;
3.服务端创建步骤:
1.创建服务端程序的端口;
2.创建管道用来接收数据;
4.socket:
(1).构造方法:
创建客户端时,常使用第二种构造方法。
如果要使用第一种构造方法,还需调用connect()方法:
socketAddress是一个抽象类,使用SocketAddress子类建立SocketAddress对象,用来封装。
SocketAddress socketaddress=new InetSocketAddress(host,ip);
(2).常用方法:
5.SeverSocket:
(1).构造方法:
常用第二种构造方法创建对象。
(2).常用方法:
6.完整代码:
(1).客户端:
package 网络通信2;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.io.Writer;
import java.io.OutputStreamWriter;
public class Client {
public static void main(String[] args) throws Exception
{
System.out.println("客户端启动了");
Scanner sc=new Scanner(System.in);
InetAddress ia=InetAddress.getLocalHost();
//1.创建socket对象,用来接通管道
Socket socket=new Socket(ia,8888);
//2.向服务端发送数据
OutputStream os=socket.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
while(true) {
System.out.println("请输入");
String ss=sc.nextLine();
if("exit".equals(ss))
{
System.out.println("退出成功");
os.close();
socket.close();
break;
}
dos.writeUTF(ss);
}
}
}
(2).服务端:
package 网络通信2;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.Reader;
import java.io.InputStreamReader;
public class Serve {
public static void main(String[] args) throws Exception
{
System.out.println("服务端启动了");
//1.创建服务端程序的端口
ServerSocket socket=new ServerSocket(8888);
//2.创建管道用来接收数据
Socket s=socket.accept();
InputStream is=s.getInputStream();
DataInputStream dis=new DataInputStream(is);
while(true) {
try {
System.out.println(dis.readUTF());}
catch(Exception e)
{
System.out.println(s.getLocalAddress().getHostAddress()+"已退出");
socket.close();
break;
}
}
}
}
四:实现多发多收:
1.UDP:
(1).客户端:
package 网络通信1;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;
public class Clientn {
public static void main(String[] args) throws Exception
{
Scanner sc=new Scanner(System.in);
DatagramSocket socket=new DatagramSocket();
//在多开客户端时,不能指定服务端的程序端口,否则会报错
while(true) {
System.out.println("请输入");
String ss=sc.nextLine();
if("exit".equals(ss)) {
System.out.println("退出成功");
socket.close();
break;}
byte[] buffer=ss.getBytes();
DatagramPacket packet=new DatagramPacket(buffer,buffer.length,InetAddress.getLocalHost(),6666);
socket.send(packet);
}
}
}
(2).服务端:
package 网络通信1;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Servern {
public static void main(String[] args) throws Exception
{
System.out.println("服务端启动成功");
DatagramSocket socket=new DatagramSocket(6666);
byte[] buffer=new byte[1024*64];
DatagramPacket packet=new DatagramPacket(buffer,buffer.length);
while(true) {
socket.receive(packet);
int len=packet.getLength();
System.out.println(new String(buffer,0,len));
System.out.println("----------------------");
}
}
}
想要实现多个客户端同时发送消息,只需将客户端多开。
2.TCP:
(1).客户端:
package 网络通信2;
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.io.Writer;
import java.io.OutputStreamWriter;
public class Client {
public static void main(String[] args) throws Exception
{
System.out.println("客户端启动了");
Scanner sc=new Scanner(System.in);
InetAddress ia=InetAddress.getLocalHost();
//1.创建socket对象,用来接通管道
Socket socket=new Socket(ia,8888);
//2.向服务端发送数据
OutputStream os=socket.getOutputStream();
DataOutputStream dos=new DataOutputStream(os);
while(true) {
System.out.println("请输入");
String ss=sc.nextLine();
if("exit".equals(ss))
{
System.out.println("退出成功");
os.close();
socket.close();
break;
}
dos.writeUTF(ss);
}
}
}
(2).服务端:
package 网络通信2;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TheadServe extends Thread{
private Socket socket;
public TheadServe(Socket socket) {
this.socket = socket;
}
public void run()
{
try {
InputStream is=socket.getInputStream();
DataInputStream dis=new DataInputStream(is);
while(true) {
try {
String s=dis.readUTF();
System.out.println(s);
}
catch (Exception e) {
dis.close();
socket.close();
}
}
}
catch(Exception e) {}
}
}
public class Serve1 {
public static void main(String[] args) throws Exception
{
ServerSocket s=new ServerSocket(8888);
while(true) {
Socket socket=s.accept();
new TheadServe(socket).start();
}
}
}
因为TCP通信安全性较高,一个客户端必须有一个服务端为之对应,所以用多线程来创建出不同的服务端。
五:UDP实现聊天功能:
package firstDemo;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test {
public static void main(String [] args)
{
new sever().start();
new client().start();
}
}
class client extends Thread
{
public void run()
{
try {
Scanner scanner=new Scanner(System.in);
System.out.println("微信聊天系统欢迎你");
System.out.println("请输入您的微信号");
int n1=scanner.nextInt();
System.out.println("请输入要发送的微信号");
int n=scanner.nextInt();
System.out.println("微信聊天系统启动");
DatagramSocket socket=new DatagramSocket();
while(true) {
String string=scanner.next();
if("exit".equals(string)) {
System.out.println("已退出");
socket.close();
break;}
byte[] buffer=string.getBytes();
DatagramPacket packet=new DatagramPacket
(buffer, buffer.length, InetAddress.getLocalHost(),n);
socket.send(packet);}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
class sever extends Thread{
public void run()
{
try {
Scanner scanner=new Scanner(System.in);
DatagramSocket socket=new DatagramSocket(4260);
byte[] buffer=new byte[64*1024];
DatagramPacket packet=new DatagramPacket(buffer,
buffer.length);
while(true) {
socket.receive(packet);
int len=packet.getLength();
System.out.println("收到"+packet.getAddress().
getHostAddress()+"--发送的数据--"+new String(buffer,0,len));}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
package firstDemo;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Test1{
public static void main(String[] args) throws Exception
{
new severs().start();
new clients().start();
}
}
class clients extends Thread
{
public void run()
{
try {
Scanner scanner=new Scanner(System.in);
System.out.println("微信聊天系统已启动");
DatagramSocket socket=new DatagramSocket();
while(true)
{
String string=scanner.nextLine();
if("exit".equals(string))
{
System.out.println("已退出");
socket.close();
break;
}
byte[] buffer=string.getBytes();
DatagramPacket packet=new DatagramPacket
(buffer, buffer.length, InetAddress.getLocalHost(),4260);
socket.send(packet);}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
class severs extends Thread{
public void run()
{
try {
DatagramSocket socket=new DatagramSocket(4250);
byte[] buffer=new byte[64*1024];
DatagramPacket packet=new DatagramPacket
(buffer, buffer.length);
while(true) {
socket.receive(packet);
int len=packet.getLength();
System.out.println("收到"+packet.getAddress().
getHostAddress()+"--发送的数据--"+new String(buffer,0,len));}
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
运行结果: