黑马程序员_Java网络编程

本文详细解析网络编程的实质、网络模型、关键要素如IP地址、端口号、传输协议以及socket概念。重点阐述了UDP与TCP两种传输方式的原理、实现步骤与区别,包括UDP的发送与接收端、TCP客户端与服务器端的建立过程,以及并发业务的处理策略。此外,文章还讨论了TCP传输中易出现的问题及其解决方案,并简述了URL结构、网络架构类型及特点。

-------    android培训java培训、期待与您交流! ----------

   网络编程的实质是两个或多个网络设备之间的数据传输,更具体的说,网络编程就是两个或多个程序之间的数据交换,和普通的单程序相比,网络程序最大不同就是需要交换数据的程序运行在不同计算机上。

网络模型:OSI七层参考模型、TCP/IP参考模型
 
网络通讯要素:
   IP地址:网络中设备的标识、
                 本地回环地址:127.0.0.1  主机名:localhost
    端口号:用于标识进程的逻辑地址,不同进程的标识
                 有效端口:0~65535,其中0~1024系统使用或保留端口
   传输协议:通讯的规则,常见协议:TCP,UDP
socket:套接字,通讯的端点
    就是为网络服务提供的一种机制,通信的两端都有Socket,网络通信其实就是Socket间的通信,数据在两个Socket间通过IO传输
 

UDP传输:

   1,只要是网络传输,必须有socket。

   2,数据一定要封装到数据包中,数据包中包括目的地址、端口、数据等信息
      对于java语言应该将udp封装成对象,易于我们的使用,这个对象就是 DatagramSocket. 封装了udp传输协议的socket对象,DatagramSocket具备发送和接受功能,在进行udp传输时,
需要明确一个是发送端,一个是接收端
    因为数据包中包含的信息较多,为了操作这些信息方便,也一样会将其封装成对象。这个数据包对象就是: DatagramPacket.通过这个对象中的方法,就可以获取到数据包中的各种信息

udp的发送端:

  1,建立udp的socket服务,创建对象时如果没有明确端口,系统会自动分配一个未被使用的端口

  2,明确要发送的具体数据

  3,将数据封装成了数据包

  4,用socket服务的send方法将数据包发送出去

  5,关闭资源

import java.net.*;
class  UdpSend{
	public static void main(String[] args)throws Exception {
                //1,建立udp的socket服务。
		DatagramSocket ds = new DatagramSocket(8888);//指定发送端口,不指定系统会随机分配。
                //2,明确要发送的具体数据。
		String text = "udp发送演示";
		byte[] buf = text.getBytes();
                //3,将数据封装成了数据包。
		DatagramPacket dp = new DatagramPacket(buf,
buf.length,InetAddress.getByName("10.1.31.127"),10000);
                //4,用socket服务的send方法将数据包发送出去。
		ds.send(dp);
                //5,关闭资源。
		ds.close();
	}
}

udp的接收端:

  1,创建udp的socket服务,必须要明确一个端口,作用在于,只有发送到这个端口的数据才是这个接收端可以处理的数据

  2,定义数据包,用于存储接收到数据

  3,通过socket服务的接收方法将收到的数据存储到数据包中

  4,通过数据包的方法获取数据包中的具体数据内容,比如ip、端口、数据等等

  5,关闭资源

class UdpRece {
	public static void main(String[] args) throws Exception{
                //1,创建udp的socket服务。
		DatagramSocket ds = new DatagramSocket(10000);
                //2,定义数据包,用于存储接收到数据。先定义字节数组,数据包会把数据存储到字节数组中。
		byte[] buf = new byte[1024];
		DatagramPacket dp = new DatagramPacket(buf,buf.length);
                //3,通过socket服务的接收方法将收到的数据存储到数据包中。
		ds.receive(dp);//该方法是阻塞式方法。
                //4,通过数据包的方法获取数据包中的具体数据内容,比如ip,端口,数据等等。
		String ip = dp.getAddress().getHostAddress();
		int port = dp.getPort();
		String text = new String(dp.getData(),0,dp.getLength());//将字节数组中的有效部分转成字符串。
		System.out.println(ip+":"+port+"--"+text);
                //5,关闭资源。
		ds.close();
	}
}

 

TCP传输:
       两个端点的建立连接后会有一个传输数据的通道,这通道称为流,而且是建立在网络基础上的流,称之为socket流。该流中既有读取,也有写入

TCP传输两个端点:   

     客户端:对应的对象,Socket

     服务端:对应的对象,ServerSocket

TCP客户端:

  1,建立tcp的socket服务,最好明确具体的地址和端口。这个对象在创建时,就已经可以对指定ip和端口进行连接(三次握手)

  2,如果连接成功,就意味着通道建立了,socket流就已经产生了。只要获取到socket流中的读取流和写入流即可,只要通过getInputStream和getOutputStream就可以获取两个流对象

  3,关闭资源  

import java.net.*;
import java.io.*;
//需求:客户端给服务器端发送一个数据。
class  TcpClient{
	public static void main(String[] args) throws Exception{
		Socket s = new Socket("10.1.31.69",10002);
		OutputStream out = s.getOutputStream();//获取了socket流中的输出流对象。
		out.write("tcp演示".getBytes());
		s.close();
	}
}

TCP服务器端

  1,创建服务端socket服务,并监听一个端口

  2,服务端为了给客户端提供服务,获取客户端的内容,可以通过accept方法获取连接过来的客户端对象

  3,可以通过获取到的socket对象中的socket流和具体的客户端进行通讯

  4,如果通讯结束,关闭资源。注意:要先关客户端,再关服务端

class  TcpServer{
	public static void main(String[] args) throws Exception{
		ServerSocket ss = new ServerSocket(10002);//建立服务端的socket服务
		Socket s = ss.accept();//获取客户端对象
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+".....connected");
                //可以通过获取到的socket对象中的socket流和具体的客户端进行通讯。
		InputStream in = s.getInputStream();//读取客户端的数据,使用客户端对象的socket读取流
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		String text = new String(buf,0,len);
		System.out.println(text);
                //如果通讯结束,关闭资源。注意:要先关客户端,再关服务端。
		s.close();
		ss.close();
	}
}

并发业务的处理

     为了可以让多个客户端同时并发访问服务端。那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求

    如何定义线程呢?只要明确了每一个客户端要在服务端执行的代码即可。将该代码存入run方法中

class PicThread implements Runnable
{
	private Socket s;
	PicThread(Socket s)
	{
		this.s = s;
	}
	public void run()
	{
		int count = 1;
		String ip  = s.getInetAddress().getHostAddress();
		try
		{
			System.out.println(ip+"....connected");

			InputStream in = s.getInputStream();

			File dir =  new File("d:\\pic");

			File file = new File(dir,ip+"("+(count)+")"+".jpg");

			while(file.exists())
				file = new File(dir,ip+"("+(count++)+")"+".jpg");

			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("上传成功".getBytes());

			fos.close();

			s.close();
		}
		catch (Exception e)
		{
			throw new RuntimeException(ip+"上传失败");
		}
	}
}


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

		while(true)
		{
			Socket s = ss.accept();

			new Thread(new PicThread(s)).start();
		}

		//ss.close();
	}
}

Tcp传输最容易出现的问题:

      客户端连接上服务端,两端都在等待,没有任何数据传输

   通过例程分析:因为read方法或者readLine方法是阻塞式
   解决办法:自定义结束标记

                    使用shutdownInput,shutdownOutput方法

URL(Uniform Resource Locater)统一资源定位符

     标准结构:协议://用户名:密码@子域名.域名.顶级域名:端口号/目录/文件名.文件后缀?参数=值#标志

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

         String getHost()         获取此 URL 的主机名(如果适用)

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

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

         String getProtocol()           获取此 URL 的协议名称

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

网络架构:

 1,C/S  client/server
   特点:
    该结构的软件,客户端和服务端都需要编写 
    可发成本较高,维护较为麻烦 
   好处:客户端在本地可以分担一部分运算 
 2,B/S  browser/server
   特点:
    该结构的软件,只开发服务器端,不开发客户端,因为客户端直接由浏览器取代
    开发成本相对低,维护更为简单 
   缺点:所有运算都要在服务端完成

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值