黑马程序员——网络编程

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
网络模型
  1)OSI参考模型
  2)TCP/IP参考模型
网络通讯要素:IP地址、端口号、传输协议
网络参考模型:
            


网络通讯要素:
1)IP地址:InetAddress
     网络中设备的标识
     不易记忆,可用主机名
     本地回环地址: 127.0.0.1 主机名: localhost
2)端口号
     用于标识进程的逻辑地址,不同进程的标识
     有效端口: 0~65535,其中0~1024系统使用或保留端口。
3)传输协议
     通讯的规则
     常见协议: TCP, UDP
TCP和UDP
UDP:
    1) 将数据及源和目的封装成数据包中,不需要建立连接
    2)每个数据报的大小在限制在64k内
    3)因无连接,是不可靠协议
    4)不需要建立连接,速度快
TCP:
    1)建立连接,形成传输数据的通道。
    2)在连接中进行大数据量传输
    3)通过三次握手完成连接,是可靠协议
    4)必须建立连接,效率会稍低

UDP传输
 DatagramSocket与DatagramPacket
建立发送端,接收端。
建立数据包。
调用Socket的发送接收方法。
关闭Socket。
发送端与接收端是两个独立的运行程序。


发送端
在发送端,要在数据包对象中明确目的地
IP及端口。
DatagramSocket ds = new DatagramSocket();
byte[] by = “hello,udp”.getBytes();
DatagramPacket dp = new DatagramPacket(by,0,by.length,
InetAddress.getByName(“127.0.0.1”),10000);
ds.send(dp);
ds.close();

接收端
在接收端,要指定监听的端口。
DatagramSocket ds = new DatagramSocket(10000);
byte[] by = new byte[1024];
DatagramPacket dp = new DatagramPacket(by,by.length);
ds.receive(dp);
String str = new String(dp.getData(),0,dp.getLength());
System.out.println(str+"--"+dp.getAddress());
ds.close();
例子:
需求:通过udp传输方式,将一段文字数据发送出去,定义一个udp发送端。

import java.net.*;
/*
思路:
1,建立updsocket服务。
2,提供数据,并将数据封装到数据包中。
3,通过socket服务的发送功能,将数据包发出去。
4,关闭资源。

*/
class  UdpSend
{
	public static void main(String[] args) throws Exception
	{
		//1,创建udp服务。通过DatagramSocket对象。
		DatagramSocket ds = new DatagramSocket(8888);

		//2,确定数据,并封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
	    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();
	}
}

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

import java.net.*;
/*
定义udp的接收端。
思路:
1,定义udpsocket服务。通常会监听一个端口。其实就是给这个接收网络应用程序定义数字标识。
	方便于明确哪些数据过来该应用程序可以处理。

2,定义一个数据包,因为要存储接收到的字节数据。
因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。
3,通过socket服务的receive方法将收到的数据存入已定义好的数据包中。
4,通过数据包对象的特有功能。将这些不同的数据取出。打印在控制台上。
5,关闭资源。

*/

class  UdpRece
{
	public static void main(String[] args) throws Exception
	{
		//1,创建udp socket,建立端点。
		DatagramSocket ds = new DatagramSocket(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();

	}
}


3)编写一个聊天工具:


/*
编写一个聊天程序。
有收数据的部分,和发数据的部分。这两部分需要同时执行。
那就需要用到多线程技术。一个线程控制收,一个线程控制发。
因为收和发动作是不一致的,所以要定义两个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"),10002);
				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("接收端失败");
		}
	}
}
class  ChatDemo
{
	public static void main(String[] args) throws Exception
	{
		DatagramSocket sendSocket = new DatagramSocket();
		DatagramSocket receSocket = new DatagramSocket(10002);
		new Thread(new Send(sendSocket)).start();
		new Thread(new Rece(receSocket)).start();

	}
}


TCP 传输
 Socket和ServerSocket
建立客户端和服务器端
建立连接后,通过Socket中的IO流进行数据的传输
关闭socket
客户端与服务器端是两个独立的应用程序。


基本思路(客户端)
客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异常。
连接成功,说明客户端与服务端建立了通道,那么通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对    象,通过getInputStream(),getOutputStream()获取即可。与服务端通讯结束后,关闭Socket。

基本思路(服务端)
服务端需要明确它要处理的数据是从哪个端口进入的。
当有客户端访问时,要明确是哪个客户端,可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据    传输。当该客户端访问结束,关闭该客户端。

客户端
通过Socket建立对象并指定要连接的服务端主机以及端口。
Socket s = new Socket(“192.168.1.1”,9999);
OutputStream out = s.getOutputStream();
out.write(“hello”.getBytes());
s.close();

服务端
建立服务端需要监听一个端口
ServerSocket ss = new ServerSocket(9999);
Socket s = ss.accept ();
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int num = in.read(buf);
String str = new String(buf,0,num);
System.out.println(s.getInetAddress().toString()+”:”+str);
s.close();
ss.close();


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

需求:给服务端发送给一个文本数据。

步骤:
1,创建Socket服务。并指定要连接的主机和端口。

*/
import java.io.*;
import java.net.*;
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("tcp ge men lai le ".getBytes());
		s.close();
	}
}


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


/*
服务端:
1,建立服务端的socket服务。ServerSocket();
	并监听一个端口。
2,获取连接过来的客户端对象。
	通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。
	并打印在控制台。
4,关闭服务端。(可选)
*/
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();
	}
}


 String getFile() 
          获取此 URL 的文件名。 
 String getHost() 
          获取此 URL 的主机名(如果适用)。 
 String getPath() 
          获取此 URL 的路径部分。 
 int getPort() 
          获取此 URL 的端口号。 
 String getProtocol() 
          获取此 URL 的协议名称。 
 String getQuery() 
          获取此 URL 的查询部 

Tcp传输最容易出现的问题
客户端连接上服务端,两端都在等待,没有任何数据传输。
解决办法:
    1)自定义结束标记
    2)使用shutdownInput, shutdownOutput方法。





  • 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、付费专栏及课程。

余额充值