TCP编程入门案例(认识Socket)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

计算机网络OSI网络模型的五层协议:应用层,运输层,网络层,数据链路层,物理层。
而TCP编程则是基于运输层,负责控制传输数据,它在传输数据之前需要先建立连接,建立连接后才能传输数据,传输完后还需要断开连接。
TCP协议是一种面向连接,可靠传输的协议


一、Socket是什么?

Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据传输到网络。
Socket、TCP和部分IP的功能都是由操作系统提供的,不同的编程语言只是提供了对操作调用的简单的封装。例如:Java提供的几个Socket相关的类就封装了操作系统提供的接口:ServerSocket类、Socket类。

二、实践案例(基于TCP协议用Socket模拟服务器和客户端)

1.案例功能

  • 通过使用ServerSocket模拟服务器,用socket模拟客户端,用客户端向服务器端发送本地磁盘的照片文件,服务端接受文件后保存并向客户端反馈信息。

2.源码及解析

  • ServerSocket模拟的服务器端

注:自定义端口号范围在1025~65535之间,小于1024的端口属于特权端口,需要管理员权限,大于1024的端口可以由任意用户的应用程序打开。

public class FileServer {
	public static void main(String[] args) {
		//监听指定端口号:
		try (ServerSocket server = new ServerSocket(8008)) {		//通过死循环,可以让服务器一直处于等待(阻塞)状态
		while(true) {
			// 让服务器处于等待状态(阻塞)
			//	accpet()方法返回Socker实例
			Socket client = server.accept();
			System.out.println("链接成功......");
			//获取客户端主机名作为接收文件后的文件名
			String fileName = String.format("%s.jpg",client.getInetAddress().getHostName());		
			//用try-with-resources机制,可以在程序运行结束时自动关闭流
			try(
			//获取字节输入流(用于接收服务器信息)
			BufferedInputStream bis = new BufferedInputStream(client.getInputStream());
			//创建字节输出流(用于向本地写入接受的文件)
			BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\test\\upload\\"+fileName));
			// 获取字节输出流(用于发送信息至客户端)
			OutputStream out = client.getOutputStream()){
				//进行写入
				byte[] buff = new byte[1024];
				int len = -1;
				while((len=bis.read(buff))!=-1){					
					bos.write(buff,0,len);					
				}
				//强制输出缓冲区至网络中
				bos.flush();
				//向客户端发送“反馈信息”
				out.write("文件上传成功".getBytes(StandardCharsets.UTF_8));
				out.flush();
			}	
		}
		}catch(IOException e){
			
		}
	}
}

  • Socket模拟的客户端
public class FileClient {
	public static void main(String[] args) {
		//指定主机ip地址和要连接的端口号
		try (Socket socket = new Socket("172.20.10.2", 8008)) {

			try (
			//获取字节输出流(用于发送客户端信息)
			BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
			//创建字节输入流(读取本地要上传的文件)
	        BufferedInputStream bis = new BufferedInputStream(
							new FileInputStream("D:\\test\\bbb\\GG-Bond.jpg"));
			// 获取字节输入流(用于读取服务器端信息)
			BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()))
					) {

				byte[] buff = new byte[1024];
				int len = -1;
				while ((len = bis.read(buff)) != -1) {
					bos.write(buff, 0, len);
				}
				bos.flush();
				//关闭本次socket的输出流
				//因为服务器是通过网络向客户端发送文件,而不是本地磁盘中获取,所以在传输完毕后要前端socket的输出流,
				//以保证程序能正常执行,否则程序会卡在循环中无法向下运行,从而无法读取反馈信息
				socket.shutdownOutput();
				// 读取服务器信息
				String message = br.readLine();
				//因为服务器端反馈的是字节信息,所以要进行处理
				message=new String(message.getBytes(),StandardCharsets.UTF_8);
				System.out.println(message);

			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}

3.运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

使用Java进行TCP编程时,需要使用Socket模型:

  • 服务器端用ServerSocket监听指定端口; 客户端使用Socket(InetAddress, port)连接服务器;
  • 服务器端用accept()接收连接并返回Socket实例;
  • 多个客户端同时连接进来,ServerSocket会把连接扔到队列里,然后一个一个处理;
  • TCP编程有着可靠、稳定、有序、点对点的特点。
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值