Java——网络编程


网络编程
在网络中发送数据分几个步骤:
1、首先要找到对方IP
2、要发到指定的应用程序上 就要对应用程序进行数字标识,这些标识叫做端口
3、定义通讯规则,称为协议,国际通用协议是TCP/IP协议,但不是唯一协议

所以网络通讯要素有三:
1、IP地址
2、端口号
3、传输协议

网络模型:
OSI模型:
   从上至下依次是:应用层 -> 表示层 -> 会话层 -> 传输层 -> 网络层 -> 数据链路层 -> 物理层
TCP/IP模型:
   从上至下依次是:应用层 -> 传输层 -> 网际层 -> 主机至网络层

IP地址:
  IP地址是网络中设备的标识
  不易记忆,可用主机名
  本地回路地址:127.0.0.1  主机名:localhost

对应的java类是InetAddress类
InetAddress类
    没有构造函数,通过静态方法getLocalHost()方法获取本类对象。
常用方法:
    getByname(String host) //通过IP地址或主机名获取主机
    getHostAddress() //获取IP地址的字符串形式
    getHostName() //获取主机名
示例:
import java.net.*;

class IPDemo
{
<span style="white-space:pre">	</span>public static void main(String[] args)throws UnknownHostException
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>InetAddress ip = InetAddress.getLocalHost();
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>System.out.println(ip.toString());
<span style="white-space:pre">		</span>System.out.println(ip.getHostAddress());
<span style="white-space:pre">		</span>System.out.println(ip.getHostName());
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>InetAddress ips[] = InetAddress.getAllByName("www.google.com");
<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>for(InetAddress i : ips)
<span style="white-space:pre">			</span>System.out.println(i.getHostAddress());
<span style="white-space:pre">	</span>}
}


UDP协议:
    特点是:面向无连接,速度快,不可靠。
    使用方法是通过DatagramSocket类建立对象,再使用DatagramPacket对象将要发送的数据封装进数据包对象,然后使用DatagramSocket对象的send()方法发送,
同时指定端口和目的主机。

下面是发送端和接收端的代码示例:
发送端:
import java.io.*;
import java.net.*;

class UdpSend
{
	public static void main(String[] args)throws SocketException,UnknownHostException,IOException
	{
		//1、通过DatagramSocket对象 创建Udp对象
		DatagramSocket ds = new DatagramSocket();
		
		//2、确定数据 封装成数据包 DategramPacket(byte[] buf, int length, 
		//										 InetAddress address, int port)
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));
		
		String line = null;
		while((line = bufr.readLine()) != null)
		{
			if(line.equals("88"))
				break;
			byte[] buf = line.getBytes();
			DatagramPacket dp = 
					new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.103"), 12322);
			
			//3、通过socket服务 将已有数据包发送出去 通过send方法
			ds.send(dp);
		}
		//4、关闭资源
		ds.close();
	}
}
接收端:
<pre name="code" class="html">import java.io.*;
import java.net.*;
class UdpRece{public static void main(String[] args)throws SocketException,UnknownHostException,IOException{DatagramSocket ds = new DatagramSocket(12322);while(true){//1、通过DatagramSocket对象 创建Udp对象//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();}}
 
 
练习:利用UDP协议实现聊天功能,一个程序同时进行收发操作,所以要利用多线程。
代码:
import java.net.*;
import java.io.*;

class ChatDemo
{
	public static void main(String[] args)throws Exception
	{
		DatagramSocket sendSock = new DatagramSocket();
		DatagramSocket receSock = new DatagramSocket(22233);

		new Thread(new Rece(receSock)).start();
		new Thread(new Send(sendSock)).start();
	}
	
}

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)
			{
				if(line.equals("end"))
					break;
				byte[] buf = line.getBytes();
				DatagramPacket dp = 
						new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.1.255"), 11112 );
				
				ds.send(dp);
			}
			ds.close();
		}catch(Exception e)
		{
			throw new RuntimeException("send failed");
		}
	}
}

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 data = new String(dp.getData(), 0, dp.getLength());
				String ip = dp.getAddress().getHostAddress();
				System.out.println(data);
			}
		}catch(Exception e)
		{
			throw new RuntimeException("reveive failed");
		}
	}
}

TCP协议:
    特点:面向连接,通过三次握手确立连接,速度较慢,可靠性高。
    使用Tcp协议,必须明确客户端和服务端,客户端使用Socket类,并在构造方法中指定目的主机地址和端口号。
服务器端使用ServerSocket类,并用accept()方法接受一个Socket对象,建立连接后,才可以传输数据。

常用方法有:
getInputStream() //获取Socket对象的输入流
getOutputStream() //获取Socket对象的输出流

示例:
import java.io.*;
import java.net.*;

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

class TcpServer
{
	public static void main(String[] args)throws Exception
	{
		//创建服务端Socket 绑定端口
		ServerSocket ss = new ServerSocket(10003);
		
		//通过accept()方法获取连接过来的客户端流对象
		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));
	}

练习:客户端接收键盘录入信息发送给服务端,服务端将其转成大写再反馈给客户端

代码:
import java.io.*;
import java.net.*;

class TClient
{
	public static void main(String[] args)throws Exception
	{
		//发送
		Socket s = new Socket("169.254.90.177", 23333);
		OutputStream out = s.getOutputStream();
		
		BufferedReader bufr = 
				new BufferedReader(new InputStreamReader(System.in));
		String line = null;
		while((line = bufr.readLine()) != null)
		{
			if(line.equals("over"))
				break;
			out.write(line.getBytes());
			
			//接收反馈
			InputStream in = s.getInputStream();
			byte[] buf = new byte[1024];
			int len = in.read(buf);
			String rData = new String(buf, 0, len);
			System.out.println(rData);
			
		}
		
		s.close();
	}
}

class TServer
{
	public static void main(String[] args)throws Exception
	{
		//接收
		ServerSocket ss = new ServerSocket(23333);
		Socket s = ss.accept();
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip + "  connected");
		InputStream in;
		OutputStream out;
		while(true)
		{
			in = s.getInputStream();
			byte[] buf = new byte[1024];
			int len = in.read(buf);
			String data = new String(buf, 0, len);
			if(data.equals("over"))
				break;
			//反馈
			String rData = data.toUpperCase();
			out = s.getOutputStream();
			out.write(rData.getBytes());
		}
	}
}

模拟实际应用:上传图片:
     客户端将本地图片发送给服务端,服务端反馈“接收成功”。
     需要注意的是,服务端应能完成同时接收多个客户端同时上传的操作,所以每接收到一个客户端Socket,都将其封装成一个线程,才能实现同时接收。
代码如下:
import java.net.*;
import java.io.*;

class ThreadClient
{
	public static void main(String[] args)throws Exception
	{
		if(args.length != 1)
		{
			System.out.println("wrong path");
			return;
		}
		
		File file = new File(args[0]);
		if(! (file.exists() && file.isFile()))
		{
			System.out.println("wrong file");
			return;
		}
		if(! file.getName().endsWith(".jpg"))
		{
			System.out.println("wrong file format");
			return;
		}
		if(file.length() > 1024 * 1024 * 3)
		{
			System.out.println("file too large");
			return;
		}
		
		Socket s = new Socket("169.254.90.177", 23335);
		FileInputStream fis = new FileInputStream(file);
		OutputStream out = s.getOutputStream();
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = fis.read(buf)) != -1)
		{
			out.write(buf, 0, len);
		}
		s.shutdownOutput();
		
		InputStream in = s.getInputStream();
		byte[] bufIn = new byte[1024];
		int lenIn = 0;
		lenIn = in.read(bufIn);
		System.out.println(new String(bufIn, 0, lenIn));
		
		s.close();
	}
}

class ThreadServer
{
	public static void main(String[] args)throws Exception
	{
		ServerSocket ss = new ServerSocket(23335);
		
		while(true)
		{
			Socket s = ss.accept();
			new Thread(new PicThread(s)).start();
		}
	}
}

class PicThread implements Runnable
{
	private Socket s;
	PicThread(Socket s)
	{
		this.s = s;
	}
	public void run()
	{
		String ip = s.getInetAddress().getHostAddress();
		try
		{
			int count = 1;
			System.out.println(ip + "  connected");
			
			File file = new File(ip + "(" + count + ")" + ".jpg");
			while(file.exists())
				file = new File(ip + "(" + count++ + ")" + ".jpg");
			InputStream in = s.getInputStream();
			FileOutputStream fos = new FileOutputStream(file);
			byte[] buf = new byte[1024];
			int len = 0;
			while((len = in.read(buf)) != -1)
			{
				fos.write(buf, 0, len);
			}
			
			OutputStream out = s.getOutputStream();
			out.write("file received".getBytes());
		}
		catch(Exception e)
		{
			throw new RuntimeException(ip +"  upload failed");
		}
	}
}

实际应用2:实现多用户登陆功能。
   建立一张用户名表,客户端接收键盘录入,发送给服务端,服务端查询用户名表,如果存在则返回登陆成功,否则返回失败,一个IP最多失败三次,然后禁止登陆。
代码:

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

class LoginClient
{
	public static void main(String[] args)throws IOException
	{
		Socket s = new Socket("169.254.90.177", 23338);
		BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter out = new PrintWriter(s.getOutputStream(), true);
		
		BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		String line = null, info = null;
		for(int i = 0; i < 3; i++)
		{
			line = bufr.readLine();
			if(line == null)
				break;
			out.println(line);
			
			info = bufIn.readLine();

			System.out.println("info: " + info);
			if(info.contains("welcome"))
				break;
		}
		
		s.close();
		bufr.close();
	}
}

class UserThread implements Runnable
{
	private Socket s;
	public UserThread(Socket s)
	{
		this.s = s;
	}
	public void run()
	{
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip + ".. connected");
		try
		{
			for(int i = 0; i < 3; i ++)
			{
				BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream()));
				String name = bufr.readLine();
				if(name == null)
					break;
				
				BufferedReader bufIn = new BufferedReader(new FileReader("user.txt"));
				String line = null;
				
				PrintWriter out = new PrintWriter(s.getOutputStream(), true);
				
				boolean found = false;
				while((line = bufIn.readLine()) != null)
				{
					if(line.equals(name))
					{
						found = true;
						break;
					}
				}
				
				if(found == true)
				{
					System.out.println(name + "  login");
					out.println("welcome  " + name );
					break;
				}else
				{
					System.out.println(name + "  try to login");
					out.println(name + "  name not found");
				}
				
			}
			
			s.close();
		}catch(Exception e)
		{
			throw new RuntimeException(ip + "  check failed");
		}
	}
}

class LoginServer
{
	public static void main(String[] args)throws IOException
	{
		ServerSocket ss = new ServerSocket(23338);
		
		while(true)
		{
			Socket s = ss.accept();
			
			new Thread(new UserThread(s)).start();
		}
		
	}
}

自定义服务端,接收来自浏览器的请求并返回信息给浏览器。
代码:
import java.net.*;
import java.io.*;

class ServerDemo
{
	public static void main(String[] args)throws IOException
	{
		ServerSocket ss = new ServerSocket(10086);
		Socket s = ss.accept();
		System.out.println(s.getInetAddress().getHostAddress() + "..connected");
		
		PrintWriter out = new PrintWriter(s.getOutputStream(), true);
		out.println("hello client");
		
	}
}

URL
     URL全称是uniform resource locator,中文是统一资源定位器,是资源的一种标识。
     对应的类是URL。
常用方法:
    构造函数:URL(String protocol,String host,int port,String file);//指定 protocol、host、port号和 file 
     String getProtocol() //获取协议名称
     String getHost() //获取主机名
     int getPort() //获取端口号
     String getFile() //获取URL文件名
     String getPath() //获取此URL的路径部分
     String getQuery() //获取此URL的查询部,客户端传输的特定信息

示例:
import java.net.*;
import java.io.*;

class URLDemo
{
	public static void main(String[] args)throws MalformedURLException
	{
		URL url = new URL("http://169.254.90.177:8080/myweb/demo.html");
		

		System.out.println("getProtocol()" + url.getProtocol());
		System.out.println("getHost()" + url.getHost());
		System.out.println("getPort()" + url.getPort());
		System.out.println("getPath()" + url.getPath());
		System.out.println("getFile()" + url.getFile());
		System.out.println("getQuery()" + url.getQuery());

	}
}

域名解析:

在浏览器地址栏中输入一个域名时,浏览器会首先在本地host文件中查询对应的IP,如果存在则直接访问,如果不存在,就请求网络供应商,访问对方的DNS服务器。
DNS服务器中存储的是大量的IP和域名的映射表,再通过映射表找到对应IP,访问对应服务器。

-----------android培训java培训、java学习型技术博客、期待与您交流!------------ 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值