网络编程

网络编程

概念

实现多台计算机之间实现数据的共享和传递,网络应用程序主要组成为:网络编程+IO流+多线程

网络编程3要素

网络通讯的模型:请求-响应,客户端-服务端

三要素:IP地址,端口,协议(数据传输的规则)

  • IP地址:网络中计算机的唯一标识
    • IP地址的组成:网络号段 + 主机段
    • 一个IP可以对应多个域名,但是一个域名在一个时刻只能对应一个IP
  • 端口号:应用程序的标识
    • 有效端口:065535,其中01024系统使用或保留端口。
    • 端口与协议有关:TCP和UDP的端口互不相干,同一个协议的端口不能重复,不同协议的可以重复
  • 协议:通信规则,就是数据的传输规则

InetAddress 类

用来表示主机的信息

  • 静态方法:getByName();
    • 在给定主机名的情况下确定主机的 IP 地址。
  • 静态方法:getLocalHost();
    • 返回本地主机的 IP。

Socket

Scoket也叫套接字,其表示的是IP地址和端口号的组合。

网络编程主要就是指Socket编程,网络间的通信其实就是Socket间的通信,数据就通过IO流在两个Scoket间进行传递。

TCP 编程

1、一对一聊天

API:Socket,ServerSocket

客户端(发送一个请求), 服务端(接收到这个请求,给予响应)

客户端

public class Client {

	@SuppressWarnings("all")
	public static void main(String[] args) throws IOException {
		
		Socket socket = new Socket("10.7.173.81",8080);//参数:IP和端口号
		
		//1.向服务端发送消息
		PrintStream ps = new PrintStream(socket.getOutputStream());
		
		ps.println("123");
		ps.println("123");
		ps.println("123");
		
		//4.接收来自服务端的消息
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		String string = br.readLine();
		System.out.println(string);
		
	}
}

服务端

public class Server {

	@SuppressWarnings("all")
	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(8080);
		
		Socket socket = server.accept();
		
		//2.接收来自客户端的消息
		BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		String string = br.readLine();
		System.out.println(string);
		
		//3.向客户端发送消息
		PrintStream ps = new PrintStream(socket.getOutputStream());
		ps.println("404!");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
}
2、优化一对一聊天

客户端

public class Client {

	@SuppressWarnings("all")
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		Socket socket = new Socket("10.7.173.81",8080);
		
		Scanner sc = new Scanner(System.in);
		//接收消息
		new ReceiveThread(socket).start();
		//发送消息
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("Client:" + sc.next());
		}
	}
}

服务端

public class Server {
	@SuppressWarnings("all")
	public static void main(String[] args) throws IOException {
		ServerSocket server = new ServerSocket(8080);
		Socket socket = server.accept();
		
		new ReceiveThread(socket).start();
		
		//发送消息
		Scanner sc = new Scanner(System.in);
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("Server:" + sc.next());
		}
	}
}

接收信息的线程类

public class ReceiveThread extends Thread{

	private Socket socket;
	
	public ReceiveThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e) {
			e.printStackTrace();
		}
		while(true){
			String string = null;
			try {
				string = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println(string);
		}
	}
}
3、传输文件

客户端

public class Client {
	
	/**
	 * 需求:传输文件
	 */
	@SuppressWarnings("all")
	public static void main(String[] args) throws UnknownHostException, IOException{
		
		Socket socket = new Socket("127.0.0.1", 8080);
		
		FileInputStream in = new FileInputStream("学习.mp4");
		OutputStream out = socket.getOutputStream();
	
		byte[] bs = new byte[1024];
		int len;
		while((len = in.read(bs)) != -1){
			out.write(bs, 0, len);
		}
	
		in.close();
		out.close();	
	}
}

服务端

public class Server {

	@SuppressWarnings("all")
	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(8080);
		
		Socket socket = server.accept();
		
		InputStream in = socket.getInputStream();
		FileOutputStream out = new FileOutputStream("download.mp4");
	
		byte[] bs = new byte[1024];
		int len;
		while((len = in.read(bs)) != -1){
			out.write(bs, 0, len);
		}
	
		in.close();
		out.close();	
	}
}
4、群聊功能

客户端

public class Client {
	/**
	 * 需求:群聊
	 */

	@SuppressWarnings("all")
	public static void main(String[] args) throws UnknownHostException, IOException {
		
		Socket socket = new Socket("127.0.0.1", 8080);
		
		Scanner scan = new Scanner(System.in);
		
		new ReceiveThread(socket).start();
		
		PrintStream ps = new PrintStream(socket.getOutputStream());
		while(true){
			ps.println("林成:" + scan.next());
		}
		
	}
}

服务端

public class Server {
	
	public static ConcurrentHashMap<InetAddress, Socket> map = new ConcurrentHashMap<>();

	@SuppressWarnings("all")
	public static void main(String[] args) throws IOException {
		
		ServerSocket server = new ServerSocket(8080);
		while(true){
			Socket socket = server.accept();
			
			//获取客户端的IP地址
			InetAddress ip = socket.getInetAddress();
			//存IP和Socket
			map.put(ip,socket);
			
			//创建线程
			new ServerThread(socket).start();
		}	
	}
}

接收信息的线程

public class ReceiveThread extends Thread{
	
	private Socket socket;
	
	public ReceiveThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		while(true){
			String readLine = null;
			try {
				readLine = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println(readLine);
		}
	}
}

发送信息的线程

public class ServerThread extends Thread{
	
	private Socket socket;
	
	public ServerThread(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		//接收当前Socket的消息
		BufferedReader br = null;
		try {
			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		while(true){
			String readLine = null;
			try {
				readLine = br.readLine();
				
				System.out.println(readLine);
				
				//发送给其他Socket
				ConcurrentHashMap<InetAddress,Socket> map = Server.map;
				Set<Entry<InetAddress,Socket>> entrySet = map.entrySet();
				for (Entry<InetAddress, Socket> entry : entrySet) {
					InetAddress key = entry.getKey();
					Socket value = entry.getValue();
					if(socket.getInetAddress() != key){
						PrintStream ps = new PrintStream(value.getOutputStream());
						ps.println(readLine);
					}
				}
				
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

UDP 编程

概念:用户数据报包协议,UDP和TCP位于同一层-传输层,但它对于数据包的顺序错误或重发没有TCP可靠;UDP是一种面向无连接的通信协议。UDP向应用程序提供一种发送封装的原始IP数据报的方法,并且发送时无需建立连接,不保证可靠数据的传输

UDP - - 发短信

TCP - - 打电话

所需要的类

DatagramPacket — 此类表示数据报包

DatagramSocket — 此类用来发送和接受数据报包的套接字

getLocalSocketAddress(); 返回此套接字绑定的端点的地址,如果尚未绑定则返回 null。

send(DatagramPacket p); 从此套接字发送数据报包。

receive(DatagramPacket p); 从此套接字接收数据报包。

SocketAddress — 抽象类,表示 IP+端口号 的组合

1、一对一聊天

客户端1

public class Client01 {
	public static void main(String[] args) throws IOException {
		/**
		 * 知识点:UDP协议
		 */
		
		//1号所在城市的快递公司
		DatagramSocket socket = new DatagramSocket();
		
		//1.1号发快递
		byte[] bs = "1号,我发礼物过来了!!".getBytes();
		DatagramPacket packet = new DatagramPacket(bs, bs.length,InetAddress.getByName("127.0.0.1"),8080);
		socket.send(packet);
		
		//4.接收2号的回礼
		byte[] buf = new byte[1024];
		packet = new DatagramPacket(buf, buf.length);
		socket.receive(packet);
		System.out.println(new String(buf).trim());
	}
}

客户端2

public class Client02 {
	public static void main(String[] args) throws IOException {
		/**
		 * 知识点:UDP协议
		 */
		
		//2号所在城市的快递公司
		DatagramSocket socket = new DatagramSocket(8080);
		
		//2.接收1号的礼物
		byte[] bs = new byte[1024];
		DatagramPacket packet = new DatagramPacket(bs, bs.length);
		socket.receive(packet);
		System.out.println(new String(bs).trim());
		
		//3.给1号回礼
		byte[] buf = "我收到礼物了,这是回礼~~".getBytes();
		packet = new DatagramPacket(buf, buf.length,packet.getSocketAddress());
		socket.send(packet);
	}
}
2、优化一对一聊天

客户端1

public class Client01 {
	public static void main(String[] args) throws SocketException {
		/**
		 * 知识点:一对一聊天
		 */
		DatagramSocket socket = new DatagramSocket(7070);
		
		new SendThread(socket, "1号", "127.0.0.1", 8081).start();
		new ReceiveThread(socket).start();
	}
}

客户端2

public class Client02 {
	public static void main(String[] args) throws SocketException {
		/**
		 * 知识点:一对一聊天
		 */
		DatagramSocket socket = new DatagramSocket(8081);
		
		new SendThread(socket, "2号", "127.0.0.1", 7070).start();
		new ReceiveThread(socket).start();
	}
}

接收信息的线程类

public class ReceiveThread extends Thread{

	private DatagramSocket socket;

	public ReceiveThread(DatagramSocket socket) {
		this.socket = socket;
	}
	
	@Override
	public void run() {

		while(true){
			byte[] bs = new byte[1024];
			DatagramPacket packet = new DatagramPacket(bs,bs.length);
			try {
				socket.receive(packet);
				System.out.println(new String(bs).trim());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

发送信息的线程类

public class SendThread extends Thread{

	private DatagramSocket socket;
	private String name;
	private String ip;
	private int port;
	
	public SendThread(DatagramSocket socket, String name, String ip, int port) {
		this.socket = socket;
		this.name = name;
		this.ip = ip;
		this.port = port;
	}

	@Override
	public void run() {

		Scanner sc = new Scanner(System.in);
		while(true){
			byte[] bs = (name + ":" + sc.next()).getBytes();
			DatagramPacket packet;
			try {
				packet = new DatagramPacket(bs, bs.length,InetAddress.getByName(ip),port);
				socket.send(packet);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值