8、网络编程

主要是两个模型

OSI模型参考模型:

物理层、数据链路层、网络层、传输层、会话层、表示层、应用层


TCP/IP参考模型

主机至网络层、网际层、传输层、应用层


网络通讯的要素

IP地址:互联网协议地址,是IP Address的缩写。是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。本地回环地址为:127.0.0.1,主机名为:LocalHost。可用此IP屏蔽垃圾网站。

Java.net包中有InetAddress类,可通过getByAddress和getByName方法来获取。地址分为IPv4和IPv6,现在主要使用的是IPv4,IPv6还在发展中。

端口号:连接软件时所需要的接口号,有效端口为0~65535,其中0~1012为系统使用或者保留端口。

传输协议:常见协议为TCP和UDP


UDP(用户数据报协议)

将数据及源和目的封装成数据包中,不需要建立连接。每个数据包的大小限制在64k内。

因无连接,所以是不可靠协议,不需要建立连接,速度快。

TCP(传输控制协议)

建立连接,形成传输数据的通道。在连接中进行大数据量传输,通过三次握手完成连接,是可靠协议

必须建立连接,效率会稍低。

Socket(网络服务端点)

Socket就是为网络服务提供的一种机制,通信两端都必须有Socket。网络通信其实就是Socket之间的通信。数据在两个Socket间通过IO传输。

UDP传输

发送端和接收端使用的都是DatagramSocket类,用来发送和接收数据包的套接字。

常用方法:void send(DatagramPacket p)发送数据报包

void reserve(DatagramPacket p)接收数据报包

DatagramPacket类,数据报包,实现无连接包投递服务,构造方法中,带地址参数的属于接收对象,不带地址参数的属于发送对象。

UDP练习:创建一个dos命令下的聊天小程序并结合多线程

package p;

import java.net.DatagramSocket;
import java.net.SocketException;

public class CharDemo {

	public static void main(String[] args) throws SocketException {
		// TODO Auto-generated method stub
		DatagramSocket send = new DatagramSocket();
		DatagramSocket rece = new DatagramSocket(10000);
		
		new Thread(new Send(send)).start();
		new Thread(new Rece(rece)).start();
	}

}


package p;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Send implements Runnable {
	
	private DatagramSocket ds;
	Send(DatagramSocket ds){
		this.ds = ds;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.print("发送端启动...");
		
		//要发送的数据
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	String s = null;
	try{
		while((s=br.readLine())!=null){

			byte[] buf = s.getBytes();
	
		//将发送的数据封装成DatagramPacket包
			DatagramPacket dp = new DatagramPacket( buf, buf.length, InetAddress.getByName("127.0.0.1"), 10000);
	
		//发送报包
			ds.send(dp);
			if("886".equals(s))
				break;
		}
	}catch(Exception e){}
	
	}

}

package p;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Rece implements Runnable {

	private DatagramSocket ds;
	Rece(DatagramSocket ds){
		this.ds = ds;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		System.out.print("接收端启动...");
		try {
			while(true){
				//创建报包储存接收到的数据
				byte[] buf = new byte[1024];
				DatagramPacket ap = new DatagramPacket(buf, buf.length);
			
				//接收数据
				ds.receive(ap);
				//报包解析数据
				String str = ap.getAddress().getHostAddress();
				int port = ap.getPort();
				String s = new String(ap.getData(),0,ap.getLength());
		
				System.out.println(str+":"+port+":"+s);
				if("886".equals(s))
					System.out.println(str+"......退出");
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}


TCP传输

客户端使用Socket类,此类实现客户端套接字,初始化时直接构造地址和端口。Socket流是底层建立好的,既有输入又有输出,想要输入和输出对象,可以用Socket类中的getOutputStream和getInputStream两个方法来实现。

Tcp传输,客户端建立的过程。
1,创建tcp客户端socket服务。使用的是Socket对象。建议该对象一创建就明确目的地。要连接的主机。 
2,如果连接建立成功,说明数据传输通道已建立。该通道就是socket流 ,是底层建立好的。 既然是流,说明这里既有输入,又有输出。想要输入或者输出流对象,可以找Socket来获取。 可以通过getOutputStream(),和getInputStream()来获取两个字节流。
3,使用输出流,将数据写出。 
4,关闭资源。 


服务端使用ServerSocket类,此类实现服务端套接字

服务端接收客户端发送过来的数据,并打印在控制台上。 
建立tcp服务端的思路:
1,创建服务端socket服务。通过ServerSocket对象。
2,服务端必须对外提供一个端口,否则客户端无法连接。
3,获取连接过来的客户端对象。
4,通过客户端对象获取socket流读取客户端发来的数据 
5,关闭资源。关客户端,关服务端。

 

由于客户端和服务端中有阻塞方法存在,所以Socket提供了shutdownInput和shutdownOutput方法,用于提示输入输出的结束,让程序跳出循环。

练习:上传文件到服务端

package p3;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 需求:上传文件
 * 1、创建客户端Socket
 * 2、读取所要上传的文件,源:file
 * 						目的:Socket
 * 3、输出数据,源:Socket
 * 				目的:服务器端
 * 4、关闭资源
 * @author Administrator
 *
 */
public class UploadClient {

	public static void main(String[] args) throws UnknownHostException, IOException {
		// TODO Auto-generated method stub

		Socket s = new Socket("192.168.1.101",10001);
		
		//创建输入流、输出流
		BufferedReader bur = new BufferedReader(new FileReader("G:\\client.txt"));
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		String line = null;
		while((line=bur.readLine())!=null){
			
			out.println(line);

		}
		s.shutdownOutput();
		
		BufferedReader burin = new BufferedReader(new InputStreamReader(s.getInputStream()));
		System.out.println(burin.readLine());
			
		bur.close();
		s.close();
	}

}

package p3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端接收客户端的数据,储存成文件
 * 思路:
 * 1、创建服务端Socket,ServerSocket。
 * 2、创建客户端对象
 * 3、读取客户端对象输出的数据
 * 4、储存获得的数据并保存到文件中
 * 5、关闭资源
 * @author Administrator
 *
 */
public class UploadServer {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		ServerSocket ss = new ServerSocket(10001);
		Socket s = ss.accept();
		String ip = s.getInetAddress().getHostAddress();
		System.out.print(ip + "......connect");
		
		BufferedReader burin = new BufferedReader(new InputStreamReader(s.getInputStream()));
		BufferedWriter burout = new BufferedWriter(new FileWriter("G:\\server.txt"));
		
		String line = null;
		while((line=burin.readLine())!=null){
			
			burout.write(line);
			burout.flush();
		}
		
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		out.println("上传成功!");
		
		burout.close();
		s.close();
		ss.close();
		
	}

}
</pre>常见的客户端是浏览器,常见的服务端是服务器。<p></p><p><span style="font-family:arial; font-size:14px; color:#333333"><span style="line-height:20.0200004577637px"><span style="white-space:pre"><span style="color:rgb(51,51,51); font-family:arial; line-height:20.0200004577637px"></span></span></span></span></p><p><span style="font-family:arial; font-size:14px; color:#333333"><span style="line-height:20.0200004577637px"><span style="white-space:pre"><span style="color:rgb(51,51,51); font-family:arial; line-height:20.0200004577637px">浏览器和服务器之间的通信是通过URL来操作的。</span></span></span></span></p><p><span style="font-family:arial; font-size:14px; color:#333333"><span style="line-height:20.0200004577637px"><span style="white-space:pre"><span style="color:rgb(51,51,51); font-family:arial; line-height:20.0200004577637px">类<code>URL</code> 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。</span></span></span></span></p><p><span style="font-family:arial; font-size:14px; color:#333333"><span style="line-height:20.0200004577637px"><span style="white-space:pre"><span style="color:rgb(51,51,51); font-family:arial; line-height:20.0200004577637px">通过URL的openConnection方法可以获得一个URLConnection对象,这个是获取URL对象的URL连接器对象,将连接封装成对象:Java中内置的可以解析具体协议的对象加Socket。</span></span></span></span></p><p><span style="font-family:arial; font-size:14px; color:#333333"><span style="line-height:20.0200004577637px"><span style="white-space:pre"><span style="color:rgb(51,51,51); font-family:arial; line-height:20.0200004577637px">通过该对象的getInputStream和getOutputStram方法可以获得输入输出字节流,可以通过流对象获取浏览器和服务器之间的数据。</span></span></span></span></p><p><span style="font-family:arial; font-size:14px; color:#333333"><span style="line-height:20.0200004577637px"><span style="white-space:pre"><span style="color:rgb(51,51,51); font-family:arial; line-height:20.0200004577637px"></span></span></span></span></p><p><span style="font-family:arial; font-size:14px; color:#333333"><span style="line-height:20.0200004577637px"><span style="white-space:pre"><span style="color:rgb(51,51,51); font-family:arial; line-height:20.0200004577637px">自定义服务器练习</span></span></span></span></p><p><span style="font-family:arial; font-size:14px; color:#333333"><span style="line-height:20.0200004577637px"><span style="white-space:pre"><span style="color:rgb(51,51,51); font-family:arial; line-height:20.0200004577637px"></span></span></span></span></p><pre name="code" class="java">package p3;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub

		ServerSocket ss = new ServerSocket(9090);
		Socket s = ss.accept();
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip + ".......connect!");
		
		InputStream in = s.getInputStream();
		byte[] buf = new byte[1024];
		int len = in.read(buf);
		System.out.print(new String(buf,0,len));
		
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		out.println("hello world!");
		
		s.close();
		ss.close();
	}

}
运行结果



自定义浏览器练习

package p3;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class MyBrowser {

	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		String str_url = "https://www.baidu.com/";
		URL url = new URL(str_url);
		URLConnection conn = url.openConnection();
		
		InputStream in = conn.getInputStream();
		byte[] buf = new byte[1024];
		int len = 0;
		while((len = in.read(buf))!=-1)
		System.out.print(new String(buf,0,len));
	}

}
运行结果



网络结构

1、C/S Slient/Server

特点:该结构的软件,客户端和服务端都需要编写,开发成本较高,维护较为麻烦。

好处:客户端在本地可以分担一部分运算。

2、B/SBrowser/Server

特点:该结构的软件只开发服务端,不开发客户端,因为客户端直接有浏览器代替,开发成本相对较低,维护更简单。

缺点:所有运算都要在服务端完成。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值