网络编程

1、网络通信协议

网络通信协议是一种网络通用语言,为连接不同操作系统和不同硬件体系结构的互联网络引提供通信支持,是一种网络通用语言。

网络通信协议由三部分组成:
语义,解释控制信息每个部分的意义。它规定了需要发出何种控制信息,以及完成的动作与做出什么样的响应。
语法,用户数据与控制信息的结构与格式,以及数据出现的顺序。
时序,对事件发生顺序的详细说明。

常见的网络通信协议有:TCP/IP协议、IPX/SPX协议、NetBEUI协议等

其中最常用的是TCP/IP协议,它是一个包括TCP协议和IP协议,UDP(User Datagram Protocal)协议和其它一些协议的协议组,该协议大致可分为四层:

应用层:主要负责应用程序的协议,如HTTP协议、FTP协议等
运输层:主要使网络程序进行通信,在进行网络通信时,可以采用TCP协议,也可以采用UDP协议。
网络层:网络层是整个TCP/IP协议的核心,它主要用于将传输的数据进行分组,将分组数据发送到目标计算机或者网络。
链路层:链路层是用于定义物理传输通道,通常是对某些网络连接设备的驱动协议,例如针对光纤、网线提供的驱动。

2、IP地址和端口号

IP地址:每台计算机的标识号,通过这个标识号来指定接受数据的计算机或者发送数据的计算机。目前,IP地址广泛使用的版本是IPv4,它是由4个字节大小的二进制数来表示,如:00001010000100000010100100000001。由于二进制形式表示的IP地址非常不便记忆和处理,因此通常会将IP地址写成十进制的形式,每个字节用一个十进制数字(0-255)表示,数字间用符号“.”分开,如 “192.168.1.100”。IPv6使用16个字节表示IP地址,它所拥有的地址容量约是IPv4的8×1028倍

端口号:如果想访问目标计算机中的某个应用程序,还需要指定端口号。在计算机中,不同的应用程序是通过端口号区分的。端口号是用两个字节(16位的二进制数)表示的,它的取值范围是065535,其中,01023之间的端口号用于一些知名的网络服务和应用,用户的普通应用程序需要使用1024以上的端口号,从而避免端口号被另外一个应用或服务所占用。
MySql:3306
tomcat:8080
Oracle:1521

3、UDP协议与TCP协议

UDP协议:其特点是面向无连接的通信协议,不保证数据的完整性,即在数据传输时,数据的发送端和接收端不建立逻辑连接。简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到数据时,也不会向发送端反馈是否收到数据。
*UDP协议消耗资源小,通信效率高

TCP协议:TCP协议的特点是面向连接的通信协议,保证数据的安全和完整性即在传输数据前先在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。
TCP协议建立客户端与服务端的连接,要经过三次握手才可以建立起来,三次握手描述如下:
第一次握手:客户端向服务端发送数据包,服务端收到客户端发送的数据包。此时服务端知道了客户端的发送能力和服务端的接收能力是正常的
第二次握手:服务端收到客户端的数据包后,向客户端返回数据包,客户端收到服务端发送的数据包。此时客户端知道了客户端的发送能力和接收能力是正常的,服务端的发送能力和接收能力是正常的。
第三次握手:客户端收到服务端返回的数据包后,向服务端发送数据包,服务端收到客户端发送的数据包。此时服务端知道了客户端的接收能力是正常的,服务端知道了服务端的发送能力是正常的。
至此,三次握手完成后,服务端与客户端都知道了彼此的发送与接收能力是正常的,通信通道确认建立起来。

4、InetAddress类
该类为Java中包括类IP地址相关的属性及方法的类,主要提供一系列与IP地址有关的方法。常用方法如下:
static InetAddress getByName(String host);//在给定主机名的情况下确定主机的IP地址,返回值为该类的实例对象
static InetAddress getLocalHost();//返回本地主机,返回值为该类的实例对象
String getHostName();//获取此IP地址的主机名
String getHostAddress();//返回IP地址字符串,以字符串形式表现

其他方法详见API。

5、UDP通信
Java中进行UDP通信的编写常用到两个类,DatagramPacket类和DatagramSocket类。其中DatagramPacket类用于封装UDP通信中接收或发送的数据。DatagramSocket用于接收和发送DatagramPacket封装的数据包。

DatagramPacket

构造方法列表如下
在这里插入图片描述
其中常用的构造方法为方法一和方法二:
DatagramPacket(byte[] buf, int length)
构造一个 DatagramPacket用于接收长度length 的数据包 。 此构造方法只能用于接收端接收数据,由于没有包含地址信息,不能作为发送端的数据包。
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
构造用于发送长度length的分组的数据报包 指定主机上到指定的端口号。此构造方法常用于发送端,该数据包包含了数据信息和地址信息,用于作为发送端的数据包

常用方法:
InetAddress getAddress();//返回某台机器的IP地址,此数据报将发往该机器或者从该机器收到
int getPort();//返回某台远程主机的端口号,此数据报将发往该机器或者从该机器收到
byte[] getData();//返回数据缓冲区
int getLength()//返回将要发送或者收到的数据的实际长度

DatagramSocket

构造方法列表:在这里插入图片描述

其中常用的两个构造方法为:

DatagramSocket();//该构造方法用于创建发送端的DatagramSocket对象,在创建DatagramSocket对象时,并没有指定端口号,此时,系统会分配一个没有被其它网络程序所使用的端口号。

DatagramSocket(int port);//该构造方法既可用于创建接收端的DatagramSocket对象,又可以创建发送端的DatagramSocket对象,在创建接收端的DatagramSocket对象时,必须要指定一个端口号,这样就可以监听指定的端口。

常用方法:
void receive(DatagramPacket p);//从此套接字接收数据报包。
send(DatagramPacket p) //从此套接字发送数据报包。

以下代码中两个类的作用为使用UDP通信发送从键盘录入的数据,发送并且接收

/**
* 发送端
 * 1,创建DatagramSocket对象
 * 2,创建DatagramPacket对象,并封装数据
 * 3,发送数据
 * 4,释放流资源
 */
            public class Sender {
            
            	public static void main(String[] args) throws Exception {
            		// TODO Auto-generated method stub
            		Scanner sc = new Scanner(System.in);
            		DatagramSocket ds = new DatagramSocket();
            		System.out.println("input data,please");
            		String sendMsg = sc.nextLine();
            		byte[] b = sendMsg.getBytes();
            		DatagramPacket dp = new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 12345);
            		ds.send(dp);
            		sc.close();
            		ds.close();
            	}
            
            }
/**
 * UDP接收端
 * 
 * 1,创建DatagramSocket对象
 * 2,创建DatagramPacket对象
 * 3,接收数据存储到DatagramPacket对象中
 * 4,获取DatagramPacket对象的内容
 * 5,释放流资源
 */
            public class Reciver {
            
            	public static void main(String[] args) throws Exception {
            		// TODO Auto-generated method stub
            		DatagramSocket ds = new DatagramSocket(12345);
            		byte[] b = new byte[1024];
            		DatagramPacket dp = new DatagramPacket(b,b.length);
            		ds.receive(dp);
            		byte[] data = dp.getData();
            		int len = dp.getLength();
            		System.out.println(new String(data,0,len));
            		ds.close();
            	}
            
            }

6、TCP通信
TCP通信中严格区分客户端与服务端,Socket类用于创建客户端对象,ServerSocket类用于创建服务端对象。

ServerSocket类
构造方法列表:
在这里插入图片描述
常用方法:
Socket accept();//侦听并接受到此套字的连接。(什么玩意???),该方法用于获取客户端对象,通过客户端对象获取输入输出流,来进行具体的数据操作。
InetAddress getInetAddress();//返回此服务器套接字的本地地址

在创建ServerSocket对象后,需要继续调用该对象的accept()方法,接收来自客户端的请求。当执行了accept()方法之后,服务器端程序会发生阻塞,直到客户端发出连接请求,accept()方法才会返回一个Scoket对象用于和客户端实现通信,程序才能继续向下执行。

Socket类

构造方法:
在这里插入图片描述

常用构造方法为:
Socket(String host,int port);//该构造方法在创建Socket对象时,会根据参数去连接在指定地址和端口上运行的服务器程序,其中host接收的是一个字符串类型的IP地址。
Socket(InetAddress address,int port);//作用同上一个方法,只是将host替换为一个封装了IP地址的InetAddress对象。

常用方法:
int getPort() ;//该方法返回一个int类型对象,该对象是Socket对象与服务器端连接的端口号
InetAddress getLocalAddress();//该方法用于获取Socket对象绑定的本地IP地址,并将IP地址封装成InetAddress类型的对象返回
void close();// 该方法用于关闭Socket连接,结束本次通信。在关闭socket之前,应将与socket相关的所有的输入/输出流全部关闭,这是因为一个良好的程序应该在执行完毕时释放所有的资源
InputStream getInputStream();//该方法返回一个InputStream类型的输入流对象,如果该对象是由服务器端的Socket返回,就用于读取客户端发送的数据,反之,用于读取服务器端发送的数据
OutputStream getOutputStream();//该方法返回一个OutputStream类型的输出流对象,如果该对象是由服务器端的Socket返回,就用于向客户端发送数据,反之,用于向服务器端发送数据

*在TCP通信中,当连接建立后,数据是通过IO流的形式进行交互,即Socket中的输入输出流。

下面的程序,三个实现类。

TCPClient类实现了读取本地的一个文件,并通过Socket发送数据到服务端,再打印出服务端的相应数据。(需要注意的是,在发送数据完成后,必须调用socket.shutdownutput();方法关闭客户端的输出流,否则服务端可能会一直处于接收状态,无法进入最后一次while循环)

TCPServer类,创建了服务端,监听TCPClient类中创建的客户端对象,读取客户端发送的数据并写入到另一个文件中,写入完成后反馈给客户端相关信息。

TCPServerThread类基本作用与TCPServer相同,只是其通过匿名内部类的方式实现了Runnable接口,并将该匿名类对象作为参数,创建线程,此时run方法中的代码操作可以实现多线程,即同时接收多个客户端发送的数据并将文件写入新的文件。

public class TCPClient {

	public static void main(String[] args) throws Exception, IOException {
		Socket socket = new Socket("127.0.0.1", 12345);
		OutputStream os = socket.getOutputStream();
		FileInputStream fis = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\TestFloder\\下载必看.txt"));
		byte[] b = new byte[1024];
		int len;
		while((len=fis.read(b))!=-1) {//一次读取一个字节数组
			os.write(b, 0, len);//调用客户端中的输出流进行字节流输出,即为发送数据
		}
		socket.shutdownOutput();//注意在客户端完成数据传输后确定没有数据继续传输了,必须关闭客户端输入流
		
		InputStream in = socket.getInputStream();
		byte[] data = new byte[1024];
		int returnLen = in.read(data);
		System.out.println(new String(data,0,returnLen));
		fis.close();
		socket.close();
	}

}
public class TCPServer {

	public static void main(String[] args) throws Exception {
		ServerSocket server = new ServerSocket(12345);
		Socket client = server.accept();
		InputStream is = client.getInputStream();
		FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\TestFloder\\receive\\1.txt"));
		byte[] b = new byte[1024];
		int len;
		while((len=is.read(b))!=-1) {
			fos.write(b, 0, len);
		}
		OutputStream os = client.getOutputStream();
		os.write("服务端已接收完毕".getBytes());
		client.shutdownOutput();
		fos.close();
		server.close();
	}

}

public class TCPServerThread {

	public static void main(String[] args) throws Exception {
		ServerSocket server = new ServerSocket(12345);
		while(true) {
			final Socket client = server.accept();
			Thread t = new Thread(new Runnable(){
				public void run() {
					try {
						InputStream is = client.getInputStream();
						FileOutputStream fos = new FileOutputStream(new File("C:\\Users\\Administrator\\Desktop\\TestFloder\\receive\\1.txt"));
						byte[] b = new byte[1024];
						int len;
						while((len=is.read(b))!=-1) {
							fos.write(b, 0, len);
						}
						OutputStream os = client.getOutputStream();
						os.write("服务端接收完毕".getBytes());
						client.shutdownOutput();
						fos.close();
					}  catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				}
				
			});
			t.start();
			
		}
		
//		server.close();
	}

}

TCP通信交互基本流程:
客户端
1,创建客户端的Socket对象
2,获取Socket的输出流对象
3,写数据给服务器
4,获取Socket的输入流对象
5,使用输入流,读反馈信息
6,关闭流资源

服务器端
1,创建服务器端ServerSocket对象,指定服务器端端口号
2,开启服务器,等待着客户端Socket对象的连接,如有客户端连接,返回客户端的Socket对象
3,通过客户端的Socket对象,获取客户端的输入流,为了实现获取客户端发来的数据
4,通过客户端的输入流,获取流中的数据
5,通过客户端的Socket对象,获取客户端的输出流,为了实现给客户端反馈信息
6,通过客户端的输出流,写数据到流中
7,关闭流资源

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值