java--11--网络编程

1 服务器端通过ServerSocket建立监听,客户端通过Socket连接到指定服务器后通信双方就可以通过IO流进行通信。
计算机网络分为物理层,数据链路程,网络层,传输层,会话层,表示层,应用层七层。
2基于TCP协议的网络编程
IP协议只能保证计算机能发送和接收分组数据,IP协议不能解决数据分组数据在传输过程中可能出现的问题。
TCP协议被称为一种端对端协议,当两台计算机连接时,TCP协议将会让他们建立一个连接,用于发送和接收数据的虚拟链路,TCP协议负责收集信息包,依次传送,
TCP使用重发机制,当一个通信实体发送一个消息给另外一个通信实体后,需要收到另外一个通信实体的确认信息,如果没有收到另外一个通信实体的确认消息,将会再次发送刚才发送的信息。
例:

/**
 * 客户端 发送数据
 * @author Shipp
 */
public class TextDemo_16 {
	public static void main(String[] args) throws IOException{
		Socket socket=new Socket("127.0.0.1",30000);
		//设置超过指定时间认为超时
		socket.setSoTimeout(10000);
		
		//另外一种连接的写法
		//Socket socket2=new Socket();
		//让Socket连接到远程服务器,设置超过时间为10000即为超时
		//socket.connect(new InetSocketAddress("127.0.0.1", 30000), 10000);
		
		//接收数据
		BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
		//读取数据
		String line=bufferedReader.readLine();
		System.out.println("来自服务器端的数据:"+line);
		socket.close();
		bufferedReader.close();
	}
}
/**
 * 服务端
 * 接收数据
 * @author Shipp
 */
public class TextDemo_15 {
	public static void main(String[] args) throws IOException{
		//没有指定IP地址,则该ServerSocket将会绑定到本机默认的IP地址
		//创建一个ServletSocket,用于监听客户端Socket的连接请求
		ServerSocket serverSocket=new ServerSocket(30000);
		//采用循环不断的接收来自客户端的请求
		while(true){
			//每当接收到客户端Socket的请求时,服务器端也会产生一个Socket
			Socket socket=serverSocket.accept();
			//将Socket对应的输入流包装成PrintStream
			PrintStream printStream=new PrintStream(socket.getOutputStream());
			//输入输出,发送数据
			printStream.println("已接收到服务器的新年祝福!");
			//关闭Socket
			socket.close();
			//关闭输入输出流,
			printStream.close();
		}
	}
}

2 基于UDP协议的网络编程
UDP协议是一种不可靠的网络协议,它在通信的两端各建立一个Socket,但是这两个Socket并没有虚拟链路,这两个Socket只是发送,接收数据包的对象。
UDP是一种面向非连接的协议,面向非连接指的是在正式通信之前不必与对方先建立连接,不管对方状态就直接发送。至于对方是否可以接收到这些数据,UDP协议无法控制。因此对于UDP协议而言,没有所谓的客户端和服务器端的概念。
例:

public class UdpClient {

	/**
	 * 定义端口号
	 */
	public static final int DEST_PORT = 30000;

	/**
	 * IP地址
	 */
	public static final String DEST_IP = "127.0.0.1";

	/**
	 * 定义接收网络数据的字节数组的长度
	 */
	private static final int DATA_LEN = 4096;

	/**
	 * 定义接收字节数组
	 */
	byte[] inBuff = new byte[DATA_LEN];

	// 以指定的字节数组创建准备接收数据的DatagramPacket对象
	private DatagramPacket inDatagramPacket = new DatagramPacket(inBuff,
			inBuff.length);

	// 用于发送数据
	private DatagramPacket outDatagramPacket = null;

	/**
	 * 客户端接收发数据
	 */
	public void initial() {
		DatagramSocket datagramSocket = null;
		try {
			// 创建一个连接
			datagramSocket = new DatagramSocket();
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 初始化发送用的DatagramSocket,
		try {
			outDatagramPacket = new DatagramPacket(new byte[0], 0,
					InetAddress.getByName(DEST_IP), DEST_PORT);
		} catch (UnknownHostException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		// 创建键盘输入流
		Scanner scanner = new Scanner(System.in);

		while (scanner.hasNextLine()) {
			byte[] buff = scanner.nextLine().getBytes();
			// 设置发送用的DatagramPacket中的字节数据
			outDatagramPacket.setData(buff);
			try {
				// 发送数据报
				datagramSocket.send(outDatagramPacket);
				// 读取Socket中的数据,读取的数据放在inDatagramPacket中
				datagramSocket.receive(inDatagramPacket);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			// 输出收到的字节
			System.out.println(new String(inBuff, 0, inDatagramPacket
					.getLength()));
		}
	}

	public static void main(String[] args) {
		new UdpClient().initial();
	}
}

public class UdpServer {

	/**
	 * 端口号
	 */
	public static final int PORT = 30000;

	/**
	 * 定义每个数据报的大小
	 */
	private static final int DATA_LEN = 4096;

	byte[] inBuff = new byte[DATA_LEN];

	// 以指定字节数组创建准备接收数据的DatagramPacket对象
	private DatagramPacket inPacket = new DatagramPacket(inBuff, inBuff.length);

	// 定义一个用于发送的DatagramPacket
	private DatagramPacket outPacket;

	// 服务器发送该数值的元素
	String[] books = new String[] { "java疯狂讲义1", "java疯狂讲义2", "java疯狂讲义3" };

	/**
	 * 接收和发送数据
	 * 
	 * @throws IOException
	 */
	public void init() throws IOException {
		DatagramSocket datagramSocket = null;
		try {
			// 创建DatagramSocket对象
			datagramSocket = new DatagramSocket(PORT);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		for (int i = 0; i < 1000; i++) {
			// 读取Socket中的数据,读到的数据放入inPacket数组中
			datagramSocket.receive(inPacket);
			System.out.println(new String(inBuff, 0, inPacket.getLength()));

			byte[] sendData = books[i % 4].getBytes();
			// 以指定的字节数组作为发送数据,以刚接收到的DatagramSocket为目标
			outPacket = new DatagramPacket(sendData, sendData.length,
					inPacket.getSocketAddress());
			// 发送数据
			datagramSocket.send(outPacket);
		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
			new UdpServer().init();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

对于Socket关闭的问题。如果关闭了流,则关闭了Socket,一般不关闭流,关闭Socket即可。
未完待续。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值