Java开发之路(13)Java基础——网络编程

一、网站编程和网络编程

1.网站编程:更基于应用的概念,通过web服务器(tomcat,jetty)封装好了网络编程的内容,只关注业务和数据

2.网络编程:更底层的,本质上接近于IO,网络端到网络端的连接和数据传递。

二、网络相关概念:

1.网络模型:
(1)七层模型
(2)TCP/IP模型
2.网络协议:
(1)TCP:建立连接,形成传输数据的通道;在连接中进行大数据量传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率会稍低。
(2)UDP:将数据源和目的封装成数据包中,不需要建立连接;每个数据报的大小限制在64k;因为无需连接,是不可靠协议,不需要建立连接,速度快。
(3)IP:IPV4和IPV6
(4)HTTP/HTTPS
3.相关命令:
ipcoonfig
ping IP
netstat

IP:互联网上让每台 主机有一个唯一的IP地址
常见的端口号:
FTP:21
mySQL:3306
oracle:1521
web:80
tomcat:8080

二、套接字Socket:

网络端与网络端的连接,连接的管道其实也是封装好的对象,管道的端其实就是一个地址。套接字就是决定网络端的地址,根据套接字可以找到对应的网络端。
IP:找到对应的唯一的主机。
端口:找到对应的主机上的进程(应用),虚拟的,针对主机上运行的对外通信的应用的一个编号。

三、网络编程的模型

1.服务器端和客户端
多个客户端可以跟一个服务器端建立联系
IO中建立管道,就是一个对象(两端)
网络编程建立管道:客户端对象,服务器端对象
客户端对象:Socket
服务器端对象:ServerSocket
2.网络编程的第一层模型
客户端设定IP和端口,就能将请求发送到对应的IP主机上的对应端口上。
服务器端server监听设置的端口,当有请求到达的时候,接收请求。
3.网络编程的第二层模型:
当有客户端请求到达服务器端的时候,server
能够监听到,生成一个新的socket对象,处理客户端请求,并且server可以继续监听新的请求。
4.网络编程的第三层模型:
通过socket,得到输入输出流,真正建立数据传输的通道。
客户端socket:输入就是向服务器端发送数据,输出就是获得服务器端数据。
服务器端socket:输入就是接收客户端数据,输出就是向客户端发送数据。

四、使用UDP协议实现网络通信:

1.InetAddress的概述和测试

InetAdress是用来表示IP地址的类。

import java.net.InetAddress;
import java.net.UnknownHostException;

/*
 * InetAddress:此类表示互联网协议(IP)地址。
 */
public class InetAddressDemo {

	public static void main(String[] args) throws UnknownHostException {
		//static InetAddress getByName(String host);
		//InetAddress address = InetAddress.getByName("LAPTOP-43VV9JPS");//发送给当前设备
		InetAddress address = InetAddress.getByName("192.168.1.107");//发送给当前设备

		System.out.println(address);
		
		String hostAddress = address.getHostName();//获取主机名
		String hostName = address.getHostAddress();//获取IP地址
		
		System.out.println(hostName);
		System.out.println(hostAddress);
	}
}

1.使用UDP协议发送数据

UDP是无需连接,不可靠传输协议,因此不管有没有接收端,发送端都可以直接运行。

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

/*
 * 使用UDP协议发送数据
 * 1.创建发送端的Socket对象、
 * 2.创建数据并打包
 * 3.发送数据
 * 4.释放资源
 * 
 * DatagramSocket:此类表示用来发送和接收收据,基于UDP协议的
 * DAtagramSocket():创建Socket对象,并随机分配端口号。
 * DAtagramSocket(int port):创建Socket对象,并指定口号。
 */
public class SendDemo {

	public static void main(String[] args) throws SocketException, IOException {
		 //* 1.创建发送端的Socket对象
		DatagramSocket ds = new DatagramSocket();
		 //* 2.创建数据并打包
		/*
		 * DatagramPacket:此类表示数据包
		 * 数据byte[]
		 * 设备地址:IP
		 * 进程的地址:端口号
		 * DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
		 */
		String s = "hello UDP";
		byte[] bys = s.getBytes();
		int length = bys.length;
		InetAddress address = InetAddress.getByName("LAPTOP-43VV9JPS");//发送给当前设备
		int port = 8888;
		//打包
		DatagramPacket dp = new DatagramPacket(bys, length, address,port) ;
		 //* 3.发送数据
		ds.send(dp);
		 //* 4.释放资源b
		ds.close();
	}
}

3.使用UDP协议接收数据

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

/*
 * 使用UDP协议接收数据
 * 1.创建接收端的Socket对象、
 * 2.接收数据并解析
 * 3.输出数据
 * 4.释放资源
 * 
 * DatagramSocket:此类表示用来发送和接收收据,基于UDP协议的
 * DAtagramSocket():创建Socket对象,并随机分配端口号。
 * DAtagramSocket(int port):创建Socket对象,并指定口号。
 */
public class ReceiveDemo {

	public static void main(String[] args) throws IOException {
		// 1.创建接收端的Socket对象
		DatagramSocket ds = new DatagramSocket(8888);
		// 2.接收数据并解析
		//DatagramPacket(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度的数据包 length 。
		byte[] bys = new byte[1024];
		DatagramPacket dp = new DatagramPacket(bys,bys.length);
		
		System.out.println(1);
		ds.receive(dp);//阻塞
		System.out.println(2);
		
			//解析数据
			//InetAddress getAddress() 返回该数据报发送或接收数据报的计算机的IP地址。 
		InetAddress address = dp.getAddress();
			//byte[] getData()返回数据缓冲区。 
		byte[] data = dp.getData();
			//int getLength() 返回要发送的数据的长度或接收到的数据的长度 
		int length = dp.getLength() ;
		// 3.输出数据
		System.out.println("send---->"+address.getHostAddress());
		System.out.println(new String(data,0,length));
		// 4.释放资源
		ds.close();
	}
}

注意事项
a.端口号错误,数据可以正常发出,不会出现异常,但是收不到数据。
b.端口号不能不能重复使用,否则会报异常(端口号已经绑定了)

五、使用TCP协议实现网络通信(客户端服务端):

TCP需要建立连接,是可靠传输协议。

1.客户端代码:

/*
 * 通过socket获得IO管道,纯IO操作。
 */
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientTest1 {

	public static void main(String[] args) throws UnknownHostException, IOException {
		// 1.建立连接到服务器端的socket
		Socket clientSocket = new Socket("192.168.1.107",1000);

		//2.客户端向服务器端发送消息:通过socket建立管道
		OutputStream os = clientSocket.getOutputStream();
		PrintWriter pw = new PrintWriter(os);
		
		pw.write("hello");
		pw.flush();
		pw.close();
		
		//3.关闭socket连接
		clientSocket.close();
	}
}

2.服务器端代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTest1 {

	public static void main(String[] args) throws IOException {
		// 1.建立serverSocket,监听对应端口
		ServerSocket server = new ServerSocket(1000);

		while(true) {
			//2.server监听端口,监听成功,生成Socket
			Socket socket = server.accept();
			
			//3.socket实现纯IO
			InputStream is = socket.getInputStream();
			BufferedReader br  = new BufferedReader(new InputStreamReader(is));
			String str = br.readLine();
			br.close();
			
			System.out.println(str);
			
			//4.本次请求的socket的关闭
			socket.close();
		}
	}
}

记录一个自己踩的小坑
我是先运行客户端代码,然后再运行服务的代码的,就报错了
Exception in thread “main” java.net.ConnectException: Connection refused: connect
解决办法:
客户端和服务器应该分别启动两个JVM,eclipse一个时刻只能运行一个程序
,可以启动两个eclipse分别运行这两个程序(两次双击eclipse图标就可以,不过第二个要创建一个新的工作区workspace)。一个eclipse也可以,但要先运行服务器端代码,然后启动客户端代码(运行前要换一个ServerSocket端口号,程序结束后上次运行程序使用的端口不会立即释放)。

3.案例练习:使用TCP协议发送数据,并将接收到的数据转换成大写返回。

客户端发出数据
服务端接收数据
服务端转换数据
服务端发出数据
客户端接收数据
(1)客户端代码

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class ClienDemo {
	/*
	 * 使用TCP协议发送数据,并将接收到的数据转换成大写返回。
	 * 1.创建发送端(客户端)Socket对象
	 * 2.获取输出流对象
	 * 3.发送数据
	 * 4.释放资源
	 */

	public static void main(String[] args) throws IOException {
		//* 1.创建发送端(客户端)Socket对象
		Socket s = new Socket(InetAddress.getByName("LAPTOP-43VV9JPS"),10010);
	    //* 2.获取输出流对象
		OutputStream os = s.getOutputStream();
		//* 3.发送数据
		os.write("tcp,im coming".getBytes());
		
		//接收数据
		//获取输入流对象
				InputStream is = s.getInputStream();
				//获取数据
				byte[] bys = new byte[1024];
				int len;
				len = is.read(bys);
				//输出数据
				String str = new String(bys,0,len);
				System.out.println(str);
		//* 4.释放资源
				s.close();
	}
}

(2)服务端代码

//1.创建服务端Socket对象
//2.监听
//3.获取输入流对象
//4.获取数据
//5.输出数据
//6.释放资源

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

public class ServerDemo {

	public static void main(String[] args) throws IOException {
		//1.创建服务端Socket对象
		ServerSocket ss = new ServerSocket(10010);
		//2.监听
		Socket s = ss.accept();
		//3.获取输入流对象
		InputStream is = s.getInputStream();
		//4.获取数据
		byte[] bys = new byte[1024];
		int len;
		len = is.read(bys);
		//5.输出数据
		String str = new String(bys,0,len);
		System.out.println(str);
		
		//转换数据
		String supperstr = str.toUpperCase();
		//获取输出流对象
		OutputStream os =s.getOutputStream();
		//发出数据
		os.write(supperstr.getBytes());
		
		//6.释放资源
		s.close();
	//	ss.close();//服务端一般不关闭
	//	is.close();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值