黑马程序员—JAVA基础—网络编程

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
一、网络通讯的要素:
       IP地址:每台网络设备的唯一标识,常用的IPv4协议,ip地址有四段0~255的数字组成
       端口号:设备中网络程序的标识号,tomcat服务器默认端口8080,mysql默认端口3306
       传输协议:TCP和UDP
二、网络通讯流程:域名解析
       由于ip地址不容易记忆,所以出现了域名概念,一个ip可以对应多个域名,但是一个域名只能对应一个ip,比如百度        
       的域名:www.baidu.com。域名可以理解为手机通讯录,手机号不容易记忆,所以将手机号标识名字。
       在浏览器中访问一个域名时,浏览器首先会访问DNS服务器,DNS服务器会根据域名找到对应的ip并返回给浏览器
       然后再根据ip地址进行访问并进行数据传输。所以当我们知道百度的ip地址,可以直接输入ip地址访问,提高速度。
三、网络参考模型:

     网络数据的传输其实就是数据打包拆包的过程:从应用层到物理层就是打包,从物理层到应用层就是拆包
     TCP/IP模型在OSI模型的基础上进行简化
四、Socket:java.net包中的一个类,这个类为网络服务提供一种机制,网络通讯的两端都有socket,数据就是在两个socket之间通过io进行传输
五、InetAddress:用于描述ip的类,此类中没有构造函数,但是有非静态方法,单例设计模式

       InetAddress getByAddress(byte[] addr) :根据原始ip地址,返回InetAddress对象 
       InetAddress getByAddress(String host, byte[] addr) :根据主机名和 IP 地址创建 InetAddress。 
       InetAddress getByName(String host) :根据主机名返回InetAddress对象 

       String getHostAddress() :获取ip地址的字符串形式
       String getHostName() :获取主机名。 
       static InetAddress getLocalHost() :返回本地主机,为静态方法

六、TCP和UDP
        UDP:面向无连接,通讯时不需要建立连接
                   将数据封装在数据报包中,且每个数据报包大小在64k内
                   因为不需要建立连接,所以是不安全的,但是传输速度快
                   一般用于聊天软件,视频通话软件等
        TCP:面向有连接,在通讯时必须建立连接,形成一个数据通道
                   通过三次握手完成连接,是安全的
                   适合大数据传输,比如下载工具等软件
代码示例1:通过UDP的形式发送和接收数据
import java.net.*;
class Send//发送端 
{
	public static void main(String[] args) throws Exception
	{
		//1.创建udp服务,通过new DatagramSocket
		DatagramSocket ds = new DatagramSocket(45000);
		//2.将字节数组封装到数据包中,
		//通过DatagramPacket(byte[] buf, int length, InetAddress address, int port)
		byte[] buf = "发送数据".getBytes();
		DatagramPacket dp = 
			new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);
		//3.将数据包发送出去,通过send方法
		ds.send(dp);
		//4.关闭资源
		ds.close();
	}
}
class Receive//接收端
{
	public static void main(String[] args) throws Exception
	{
		//1.创建udp服务,通过new DatagramSocket,设定端口
		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);
			String data = new String(dp.getData(),0,dp.getLength());
			String ip = dp.getAddress().getHostAddress();//获取发送端的ip
			int port = dp.getPort();//获取发送端的端口号
			System.out.println(ip+"::"+port+"::"+data);
		}
		//关闭资源
		ds.close();
	}
}
代码示例2:使用TCP的方式发送和接收数据
import java.io.*;
import java.net.*;
class TcpClient 
{
	public static void main(String[] args) throws Exception
	{
		//创建socket服务,指定主机和端口
		Socket s = new Socket("192.168.1.100",10003);
		//获取输出流,用于发送数据
		OutputStream out = s.getOutputStream();
		out.write("客户端数据".getBytes());
		s.close();
	}
}
class TcpService
{
	public static void main(String[] args) throws Exception
	{
		//创建服务端socket服务,并监听端口
		ServerSocket ss = new ServerSocket(10003);
		//通过accept方法获取连接的客户端对象
		Socket s = ss.accept();
		//获取ip
		String ip = s.getInetAddress().getHostAddress();//获取ip
		System.out.println(ip+"连接了!");
		//通过客户端对象获取客户端的输入流
		InputStream in = s.getInputStream();
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String data = new String(buf,0,len);
		int port = s.getPort();//获取端口
		System.out.println(ip+"::"+port+"::"+data);
		s.close();
	}
}
练习1:使用TCP进行文件复制,也就是客户端上传文件到服务器
import java.io.*;
import java.net.*;
class Client 
{
	public static void main(String[] args)throws Exception 
	{
		//建立socket服务,指定ip和端口号
		Socket s = new Socket("192.168.1.110",10005);
		//定义字符缓冲流对象,用于读取将要复制的文件
		BufferedReader bfr = 
			new BufferedReader(new FileReader("UploadText.java"));
		//定义打印流对象,用于传输数据给服务器
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		String line =null;
		while ((line=bfr.readLine())!=null)
		{
			out.println(line);
		}
		//传输完毕后,关闭socket中的输出流,告诉服务器,数据已经传输完毕
		s.shutdownOutput();
		//定义字符输入流对象,用于读取服务器返回的数据
		BufferedReader bfr2 = 
			new BufferedReader(new InputStreamReader(s.getInputStream()));
		String str = bfr2.readLine();
		System.out.println(str);
		bfr.close();
		s.close();
	}
}
class Server
{
	public static void main(String[] args)throws Exception 
	{
		//建立服务器中ServerSocket对象
		ServerSocket ss = new ServerSocket(10005);
		//通过accept方法获取客户端的socket对象
		Socket s = ss.accept();
		String ip = s.getInetAddress().getHostAddress();//获取ip地址
		System.out.println(ip+"连接了!");
		//定义打印流,用于将数据写入新文件
		PrintWriter pw = new PrintWriter(new FileWriter("copy.txt"),true);
		BufferedReader bfw2 =
			new BufferedReader(new InputStreamReader(s.getInputStream()));
		String line = null;
		while ((line=bfw2.readLine())!=null)
		{
			pw.println(line);
		}
		//定义打印流,将提示信息返给客户端
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		out.println("上传成功!");
		pw.close();
		s.close();
		ss.close();
	}
}
练习2:多线程下上传图片,实现多用户上传并且可以指定文件
import java.io.*;
import java.net.*;
//客户端类
class Client
{
	public static void main(String[] args)throws Exception 
	{
		//args为用户传入的文件绝对路径
		if (args.length!=1)
		{
			System.out.println("请选择一个jpg文件");
			return ;
		}
		//定义文件对象
		File f = new File(args[0]);
		//判断是否存在和是否是文件
		if (!(f.exists() && f.isFile()))
		{
			System.out.println("文件不存在或者不是jpg文件");
			return ;
		}
		//判断是否为jpg文件
		if (!(f.getName().endsWith(".jpg")))
		{
			System.out.println("请选择一个jpg文件");
			return ;
		}
		//为了防止用于将过大的文件更改后缀名上传,可以进行判断文件大小
		if (f.length()>1024*1024*8)
		{
			System.out.println("文件超过限制大小");
			return ;
		}
		//建立socket服务,指定ip和端口
		Socket s = new Socket("192.168.1.110",10006);
		//定义字节缓冲流兑现,用于读取文件
		BufferedInputStream bfis =
			new BufferedInputStream(new FileInputStream(f));
		OutputStream out = s.getOutputStream();
		int by = 0;
		while ((by=bfis.read())!=-1)
		{
			out.write(by);
			out.flush();
		}
		s.shutdownOutput();//传输完毕后关闭流

		//用于读取服务器返回的信息
		InputStream in = s.getInputStream();
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String info = new String(buf,0,len);
		System.out.println(info);
		bfis.close();//先关闭流
		s.close();//再关闭socket
	}
}
//服务器端多线程类
class PicThread implements Runnable
{
	private Socket s;
	PicThread(Socket s)//将客户端的socket作为构造函数的参数,一初始化就要有socket
	{
		this.s = s;
	}
	public void run()
	{
		int count = 1;//定义计数器,用于上传一样文件时,给文件命名
		String ip = s.getInetAddress().getHostAddress();
		try
		{
			System.out.println(ip+"连接了!");
			BufferedInputStream bfis = 
				new BufferedInputStream(s.getInputStream());
			File file = new File(ip+"("+count+")"+".jpg");
			//判断文件是否存在,存在就计数器就加1给文件命名
			while (file.exists())
			{
				file = new File(ip+"("+(count++)+")"+".jpg");
			}
			FileOutputStream fos = new FileOutputStream(file);
			int by = 0;
			while ((by=bfis.read())!=-1)
			{
				fos.write(by);
			}
			OutputStream out = s.getOutputStream();
			out.write("上传成功".getBytes());//返回数据给客户端
			fos.close();
			s.close();
		}
		catch (Exception e)
		{
			throw new RuntimeException("上传图片失败");
		}
	}
}
class Server
{
	public static void main(String[] args)throws Exception 
	{
		ServerSocket ss = new ServerSocket(10006);
		//while可以继续上传
		while (true)
		{
			Socket s = ss.accept();
			new Thread(new PicThread(s)).start();
		}	
	}
}
六、tomcat服务器:免费开源的javaweb服务器,我们也可以自定义服务器。

七、URL和URLConnection
       URL:是一个浏览器地址封装类
       常用方法
          String getFile() :获取此 URL 的文件名。 
          String getHost() :获取此 URL 的主机名(如果适用)。 
          String getPath() :获取此 URL 的路径部分。 
          int getPort() :获取此 URL 的端口号。 
          String getProtocol() :获取此 URL 的协议名称。 
          String getQuery() :获取此 URL 的查询部
      URLConnection:将socket进行封装,提供更方便的访问服务器的方法
      通过getInputStream获取socket中的输入流对象


                   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值