Java-网络编程

一:InetAddress:

该类用于封装一个ip地址。

5460386fa5114cb598644b8dc42434bf.jpeg

二: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).构造方法:

2878ff09053c422794da028af009920f.png

常见的构造方法有两种,一种是不带参数的,一种是以端口号为参数的。一般客户端创建DatagramSocket对象使用无参的构造方法,而服务端则使用有参的构造方法。

(2).常用方法:

21fa62d2048c44889ece8399f5cfbb0c.jpeg

 5.DatagramPacket:

(1).构造方法:

269f27c4743c4823b4ec9ebe5dea9fd6.png

常用的构造方法为前两种,客户端常用第二种构造方法,服务端常用第一种构造方法 。

(2).常用方法:

e28fe7cd46be417889ad5db6851f21fa.jpeg

 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).构造方法:

f3a6d8be961e4115b9b80cfdc404b977.png

创建客户端时,常使用第二种构造方法。 

 如果要使用第一种构造方法,还需调用connect()方法:62e711247d14480fa9f1b22b458363f6.png

 socketAddress是一个抽象类,使用SocketAddress子类建立SocketAddress对象,用来封装。

SocketAddress socketaddress=new InetSocketAddress(host,ip);

88118046d3d649a0aa967be624cb5695.png

(2).常用方法:

285cba5b0a4042448a39bcb2574d4a9b.jpeg

5.SeverSocket:

(1).构造方法:

de83a98c1f4c4472a49adc5b57b8a65b.png

 常用第二种构造方法创建对象。

 (2).常用方法:7037dae9bbc0457fa51afdb6dbda4ee4.jpeg

 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();
		}
 		
	}
}

 运行结果:

95206fda52d54288947d65e47f0776d0.png

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值