黑马程序员——网络编程

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

网络编程概述

网络通讯要素:

IP地址:InetAddress

网络中的设备标识,不易记忆,可用主机名

本地回环地址:127.0.0.1     主机名:localhost

端口号:

用于标识进程中的逻辑地址,不同进程的标识,数据要发送到对方指定的应用程序上,为了标识这些应用程序,给这些网络应用程序都用数字进行标识。

有效端口:0-65535,其中0-1024系统使用或保留端口

传输协议:通讯的规则

常见协议:TCP UDP

常用方法:

Static  InetAddress   getByName(String host) 给定主机名,确定主机的IP地址

static  InetAddress  getLocalHost() 返回本地主机

String  getHostAddress() 返回IP地址字符串

String  getHostName() 获取此IP地址的主机

UDP特点:

1、面向无连接,不需要建立连接,将数据及源封装成数据包

2、每个数据包大小限制在64k内

3、不可靠协议,因无连接

4、不需要建立连接,速度快

eg:QQ等聊天工具,网络视频会议,桌面共享

TCP特点:

1、面向连接,必须先连接,形成传输数据的通道

2、进行大数据量传输

3、通过三次握手完成连接,是可靠协议

4、效率稍低,必须建立连接

eg:下载

Socket:

Socket就是为网络服务提供的一种机制

通信的两端都有socket

网络通信其实就是socket间的通信

数据在两个Socket间通过IO传输

 

UDP

步骤:

1、建立发送端,接收端

2、建立数据包

3、调用Socket的发送接收方法

4、关闭Socket

UDP常用方法

DatagramSocket() 创建数据报套接字并将其绑定到本地主机上的指定端口

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

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

DatagramPacket(byte[] buf, int length,InetAddressaddress,int port)  构造数据报包,用来将长度为length 的包发送到指定主机上的指定端口号

InetAddress getAddress()返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收到的

byte[]  getDate() 返回数据缓冲区

int getLength() 返回将要发送或接收到的数据的长度

int getPort() 返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到

 

需求:通过udp传输方式,将一段文字数据发送出去

分析:定义一个udp发送端

思路:

1、建立updsocket服务

2、提供数据,并将数据封装到数据包中

3、通过socket服务的发送功能,将数据包发出去

4、关闭资源

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UdpSend {
	public static void main(String[] args) throws Exception {
		// 1、通过DatagramSocket对象创建udp服务
		DatagramSocket ds = new DatagramSocket(8888); // 给发送端固定一个发送端口
		// 2、确定数据,并封装成数据包
		byte[] buf = "udp ge men lai le ".getBytes();
		DatagramPacket dp = new DatagramPacket(buf, buf.length,
				InetAddress.getByName("192.168.1.254"), 10000);
		// 3、通过socket服务的send方法将已有的数据包发送出去
		ds.send(dp);
		// 4、关闭资源
		ds.close();
	}
}


需求:定义一个应用程序,用于接收udp协议传输的数据并处理的

分析:定义udp的接收端

思路:

1、定义udpsocket服务,通常会监听一个端口,就是给这个接收网络应用程序定义数字标识,方便于明确哪些数据过来该应用程序可以处理

2、定义一个数据包,因为要存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息

3、通过socket服务的receive方法将收到的数据存入已定义好的数据包中

4、通过数据包对象的特有功能,将这些不同的数据取出打印在控制台上

5、关闭资源

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UdpRece {
	public static void main(String[] args) throws Exception {
		// 1、创建udp socket,建立端点
		DatagramSocket ds = new DatagramSocket(10000);// 给接收端绑定10000端口,用于接受发送端来的数据
		while (true) {
			// 2、定义数据包,用于存储数据
			byte[] buf = new byte[1024];
			DatagramPacket dp = new DatagramPacket(buf, buf.length);

			// 3、通过服务的receive方法将收到数据存入数据包中
			ds.receive(dp);// 阻塞式方法

			// 4、通过数据包的方法获取其中的数据
			String ip = dp.getAddress().getHostAddress();
			String data = new String(dp.getData(), 0, dp.getLength());
			int port = dp.getPort();
			System.out.println(ip + "::" + data + "::" + port);
		}
		// 5、关闭资源
		// ds.close();
	}
}


需求:编写一个聊天程序。要求:有收数据的部分,和发数据的部分,这两部分需要同时执行。

分析:发送和接受数据同时执行,就需要用到多线程技术,一个线程控制收,一个线程控制发

因为收和发动作是不一致的,所以要定义两个run方法,而且这两个方法要封装到不同的类中。

import java.io.*;
import java.net.*;

//发送端
class Send implements Runnable {
	private DatagramSocket ds;

	public Send(DatagramSocket ds) {
		this.ds = ds;
	}

	public void run() {
		try {
			BufferedReader bufr = new BufferedReader(new InputStreamReader(
					System.in));
			String line = null;
			while ((line = bufr.readLine()) != null) {
				byte[] buf = line.getBytes();
				DatagramPacket dp = new DatagramPacket(buf, buf.length,
						InetAddress.getByName("192.168.1.255"), 10021);
				ds.send(dp);
				if ("886".equals(line))
					break;
			}
		} catch (Exception e) {
			throw new RuntimeException("发送端失败");
		}
	}
}

// 接收端
class Rece implements Runnable {
	private DatagramSocket ds;

	public Rece(DatagramSocket ds) {
		this.ds = ds;
	}

	public void run() {
		try {
			while (true) {
				byte[] buf = new byte[1024];
				DatagramPacket dp = new DatagramPacket(buf, buf.length);

				ds.receive(dp);
				String ip = dp.getAddress().getHostAddress();
				String data = new String(dp.getData(), 0, dp.getLength());
				if ("886".equals(data)) {
					System.out.println(ip + "....离开聊天室");
					break;
				}
				System.out.println(ip + ":" + data);
			}
		} catch (Exception e) {
			throw new RuntimeException("接收端失败");
		}
	}
}

public class ChatDemo {
	public static void main(String[] args) throws Exception {
		DatagramSocket sendSocket = new DatagramSocket();
		DatagramSocket receSocket = new DatagramSocket(10021);

		new Thread(new Send(sendSocket)).start();// 开启发送端线程
		new Thread(new Rece(receSocket)).start();// 开启接收端线程

	}
}


TCP传输

tcp分客户端和服务端

客户端对应的对象是Socket

服务端对应的对象是ServerSocket。

操作步骤:

建立客户端和服务端

建立连接后,通过Socket中的IO流进行数据的传输

关闭socket

TCP常用方法

Socket(InetAddress address , int port)  创建一个流套接字并将其连接到指定 IP 地址的指定端口号

InputStream  getInputStream()  返回此套接字的输入流

OutputStream  getOutputStream()返回此套接字的输出流

InetAddress  getInetAddress()返回套接字连接的地址

ServerSocket(int port) 创建绑定到特定端口的服务器套接字

Socket accept() 侦听并接受到此套接字的连接

创建客户端基本思路:

1、客户端需要明确服务器的ip地址及端口,这样才可以去试着建立连接,如果连接失败,会出现异常

2、连接成功,说明客户端和服务端建立了通道,就可以通过IO流进行数据的传递,而Socket对象已经提供了输入流和输出流对象通过getInputStream(),getOutputStream()获取即可

3、与服务器端通讯结束后,关闭Socket

通过查阅socket对象,发现在该对象建立时,就可以去连接指定主机,因为tcp是面向连接的。所以在建立socket服务时,就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输。

创建服务端的基本思路

1、  服务端需要明确它要处理的数据是从哪个端口进入的

2、  当有客户端访问时,要明确是哪个客户端,可以通过accept()获取已经连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输

3、  当该客户端访问结束,关闭该客户端

需求:定义端点接收数据并打印在控制台上。

步骤:

1、建立服务端的socket服务,ServerSocket();并监听一个端口

2、获取连接过来的客户端对象,通过ServerSokcet的 accept方法,没有连接就会等,所以这个方法阻塞式的

3、客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据,并打印在控制台

4、关闭服务端。(可选)

import java.io.*;
import java.net.*;

//创建客户端
public class TcpClient {
	public static void main(String[] args) throws Exception {
		// 创建客户端的socket服务。指定目的主机和端口
		Socket s = new Socket("192.168.1.254", 10003);
		// 为了发送数据,应该获取socket流中的输出流
		OutputStream out = s.getOutputStream();
		out.write("tcpge men lai le ".getBytes());
		s.close();
	}
}

// 创建服务端
class TcpServer {
	public static void main(String[] args) throws Exception {
		// 建立服务端socket服务。并监听一个端口。
		ServerSocket ss = new ServerSocket(10003);

		// 通过accept方法获取连接过来的客户端对象。
		while (true) {
			Socket s = ss.accept();
			String ip = s.getInetAddress().getHostAddress();
			System.out.println(ip + ".....connected");

			// 获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。
			InputStream in = s.getInputStream();

			byte[] buf = new byte[1024];
			int len = in.read(buf);
			System.out.println(new String(buf, 0, len));
			s.close();// 关闭客户端.
		}
		// ss.close();
	}
}

需求:建立一个文本转换服务器,客户端给服务端发送文本,服务端会将文本转成大写在返回给客户端。

而且客户度可以不断的进行文本转换,当客户端输入over时,转换结束。

分析:

客户端:

源:键盘录入

目的:网络设备,网络输出流

而且操作的是文本数据,可以选择字符流,同时提高效率,加入缓冲。

步骤

1、建立服务

2、获取键盘录入

3、将数据发给服务端

4、后去服务端返回的大写数据

5、结束,关资源

import java.io.*;
import java.net.*;
public class TransClient {
	public static void main(String[] args) throws Exception {
		Socket s = new Socket("192.168.1.254", 10005);
		// 定义读取键盘数据的流对象。
		BufferedReader bufr = new BufferedReader(new InputStreamReader(
				System.in));

		// 定义目的,将数据写入到socket输出流。发给服务端。
		/*
		 * BufferedWriter bufOut = new BufferedWriter(new
		 * OutputStreamWriter(s.getOutputStream()));
		 */
		PrintWriter out = new PrintWriter(s.getOutputStream(), true);
		// 定义一个socket读取流,读取服务端返回的大写信息。
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(
				s.getInputStream()));

		String line = null;
		while ((line = bufr.readLine()) != null) {
			if ("over".equals(line))
				break;

			out.println(line);

			String str = bufIn.readLine();
			System.out.println("server:" + str);

		}
		bufr.close();
		s.close();
	}
}


服务端:

源:socket读取流

目的:socket输出流

都是文本,装饰设计模式

class TransServer {
	public static void main(String[] args) throws Exception {
		ServerSocket ss = new ServerSocket(10005);

		Socket s = ss.accept();
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip + "....connected");

		// 读取socket读取流中的数据。
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(
				s.getInputStream()));

		// 目的socket输出流,将大写数据写入到socket输出流,并发送给客户端。

		PrintWriter out = new PrintWriter(s.getOutputStream(), true);

		String line = null;
		while ((line = bufIn.readLine()) != null) {
			System.out.println(line);
			out.println(line.toUpperCase());

		}
		s.close();
		ss.close();
	}
}

在运行改程序时发现客户端和服务端都在莫名的等待,因为客户端和服务端都有阻塞式方法,这些方法么没有读到结束标记,那么就一直等而导致两端,都在等待。

 

URL

 URL 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。

URL常用方法

URL(string spec)  根据 String 表示形式创建URL 对象

String getFile()   获取此UR的文件名

String getHost()   获取此URL的主机名

String getPath()   获取此URL的路径部分

int getPort()    获取此URL的端口号

String getProtocal() 获取URL的协议名称

String getQuery()  获取此URL的查询部分

URLConnection openConnection() 返回一个URLConnection 对象,它表示到URL 所引用的远程对象的连接

InputStream getInputStream() 返回从此打开的连接读取的输入流


------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑马程序员的tb_brand是指在JavaWeb基础教程中创建的一个表。这个表是用来存储品牌信息的,具体的表结构和数据类型需要和JavaBean类中的成员变量保持一致。\[1\]在这个教程中,使用了Maven来构建项目,并且使用了MyBatis作为持久层框架,通过配置pom.xml文件来引入相关依赖。\[2\] Maven是一个用于管理和构建Java项目的工具,它提供了一套标准化的项目结构、构建流程和依赖管理机制。\[3\] #### 引用[.reference_title] - *1* [【JAVAWEB开发】黑马程序员java web案例资料(含Element的删除与修改)](https://blog.csdn.net/aasd23/article/details/126940147)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [黑马程序员-MyBatis 框架-最全入门笔记、阿伟看了都得说真大、真细、真全!!!](https://blog.csdn.net/qq_57383364/article/details/128103058)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [JavaWeb——黑马程序员课程笔记](https://blog.csdn.net/King_ZACC/article/details/128573804)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值