Socket网络编程

本文主要介绍了网络编程的相关知识,首先介绍了互联网的相关概念和常见的体系架构,之后介绍了两种网络编程(TCP与UDP),并给出了代码实现!

一、名词概念

  • 互联网(Internet): 点与点相连
  • 万维网(www-world wide web): 端与端相连
  • 物联网(IoT-Internet of things): 物与物相连
  • 网络编程: 让计算机与计算机之间建立连接,进行通讯

二、网络架构

1.分层结构

在这里插入图片描述


2.OSI网络架构

  • 简介: Open System Interconnect (开放式系统互连)
  • 特点: 存在于概念和理论上的一种模型,它的缺点是分层太多,增加了网络工作的复杂性,所以没有大规模应用
    在这里插入图片描述
  • 第一层: :物理层为设备之间的数据通信提供传输信号和物理介质。(双绞线、 光导纤维)
    作用: 建立、维护、断开物理连接。
  • 第二层: 链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)
    作用: 接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,
    拆装为位流形式的数据转发到物理层;并且,还负责处理接收端发回的确认帧的信息,以便提供可靠的数据传
    输。
  • 第三层: 网络层负责定义了能够标识所有网络节点的逻辑地址。(IP地址)
    作用: 逻辑寻址,IP地址,在下两层的基础上向资源子网提供服务
  • 第四层: 传输层负责是否选择差错恢复协议、数据流重用、错误顺序重排。(TCP、 UDP)
    作用: 提供可靠和不可靠的传输机制,TCP、UDP
  • 第五层: 会话层负责使应用建立和维持会话,使通信在失效时继续恢复通信。(断点续传).
    作用: 建立、终止、管理实体间的会话连接
  • 第六层: 表示层负责定义转换数据格式及加密,允许选择以二进制或ASCII格式传输。
    作用: 封装数据的格式(加密解密、压缩解压缩)
  • 第七层: 应用层负责文件访问和管理、可靠运输服务、远程操作服务。(HTTP、 FTP、SMTP)
    作用: 人与机器电脑交互的窗口

3.TCP/IP网络架构

在这里插入图片描述

  • TCP协议: TCP协议: Transmission Control Protocol(传输控制协议)
    解释: 是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
  • UDP协议: User Datagram Protocol用户数据报协议
    解释: 是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB。

IP协议: Internet Protocol Address(互联网协议地址/网际协议地址)

  • 解释: 分配给互联网设备的数字标签(唯标识)。—— 计算机在互联网中的地址
  • 分类:

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

IPV6
在这里插入图片描述

IP对应类:InetAddress: 代码示例

public static void main(String[] args) throws IOException {
		//获取本机地址
		InetAddress inetAddress=InetAddress.getLocalHost();
		System.out.println(inetAddress);
		//通过主机名获取地址
		InetAddress idAddress=InetAddress.getByName("DESKTOP-1028");
		System.out.println(idAddress);
		//通过主机名获取所有相关的地址对象
		InetAddress[] inetAddresses = InetAddress.getAllByName("www.baidu.com");
		for (InetAddress inetAddress2 : inetAddresses) {
			System.out.println(inetAddress2);
		}
		//通过地址对象获取主机地址和主机名称
		String hostAddress = inetAddress.getHostAddress();
		String hostName = inetAddress.getHostName();
		System.out.println(hostAddress);
		System.out.println(hostName);
	}

二、网络编程

1.Port端口

  • 端口号: 在通信实体上进行网络通讯的 程序 的唯一标识。
  • 端口分类:
    公认端口: 0~1023
    注册端口: 1024~49151
    动态或私有端口: 49152~65535
  • 常用端口:
    MySql: 3306
    Oracle: 1521
    Tomcat: 8080
    SMTP: 25
    Web服务器: 80
    FTP服务器: 21

2.Socket编程

  • Socket: 套接字,网络中的一个节点
  • 通讯要求: IP地址+端口号

1.TCP编程

  • 简介: 是一种面向连接的、可靠的、基于字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
  • 注意: 分为客户端Scoket与服务器ServerSocket

开发步骤:

  • 通过Socket获取到流,服务器才可以和客户端进行数据交互
  • 服务端:ServerSocket
    1,创建ServerSocket,指定端口
    2,调用accept等待客户端接入(获取到客户端Socket映射)
    3,使用Socket输入流或输出流,与客户端进行数据交互
    4,关闭释放资源
  • 客户端:Socket
    1,创建Socket对象,指定服务器IP+端口(获取到服务器Socket映射)
    2,使用Socket获取到输出流,发起请求,给服务器发生数据(可选)
    3,使用Socket获取到输入流,接收服务器返回的数据(可选)
    4,关闭释放资源
TCP编程示例01:无间断双向聊天

Task.java线程任务

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Task {	
	private Socket socket;	
	public Task() {
		super();
	}
	public Task(Socket socket) {
		super();
		this.socket = socket;
	}
	//服务器功能线程
	public void Message() {
		//创建线程池(保证接收同步)
		ExecutorService pool = Executors.newFixedThreadPool(2);		
		//接收消息线程
		pool.submit(new Runnable() {
			@Override
			public void run() {
				try {
					//输入流
					InputStream is = socket.getInputStream();
					InputStreamReader isr=new InputStreamReader(is);
					BufferedReader br=new BufferedReader(isr);
					while(true) {
						String str = br.readLine();
						System.out.println(str);
						//判断是否关闭程序
						if (str.equals("886")) {
							break;
						}
					}
					//关流
					is.close();
					socket.close();
					isr.close();
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
				}			
			}
		});		
		//发送消息线程
		pool.submit(new Runnable() {		
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					OutputStream os = socket.getOutputStream();
					OutputStreamWriter osw=new OutputStreamWriter(os);
					BufferedWriter bw=new BufferedWriter(osw);					
					Scanner scanner=new Scanner(System.in);		
					//循环
					while(true) {
						String str=scanner.next();
						bw.write(str);
						bw.newLine();
						bw.flush();
						//跳出循环
						if (str.equals("886")) {
							break;
						}
					}
					//关流
					os.close();
					socket.close();
					osw.close();
					bw.close();
				} catch (IOException e) {
					e.printStackTrace();
				}				
			}
		});		
	}	
}

Server.java服务器端

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

public class Server {
	public static void main(String[] args) throws IOException {
		ServerSocket serverSocket=new ServerSocket(8899);
		//获取到客户端映射
		Socket socket=serverSocket.accept();
		Task task=new Task(socket);
		task.Message();
	}
}

Client.java服务器端

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {

public static void main(String[] args) throws UnknownHostException, IOException{
		// TODO Auto-generated method stub
		Socket socket=new Socket("10.35.162.54", 9900);
		Task task=new Task(socket);
		task.Message();
	}
**TCP编程示例02:文件上传 **

Client.java服务器端

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket socket=new Socket("127.0.0.1", 8989);
		System.out.println(socket.getInetAddress());
		//获取输入流与输出流(与服务器交互)
		InputStream is=socket.getInputStream();
		OutputStream os=socket.getOutputStream();
		//创建文件输入流(读取本地文件)
		FileInputStream fis=new FileInputStream("E:\\dog.jpeg");
		byte[] bytes=new byte[1024];
		int len=0;
		while((len=fis.read(bytes))!=-1) {
			os.write(bytes, 0, len);
			os.flush();
		}
		//获取服务器返回信息
		len=is.read(bytes);
		String str=new String(bytes, 0, len);
		System.out.println(str);
	}
}

注意:程序中服务器端文件流读取判断
Server.java服务器端

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		ServerSocket serverSocket = new ServerSocket(8989);
		Socket socket = serverSocket.accept();
		//获取输入流与输出流(用于和客户端交互)
		InputStream is = socket.getInputStream();
		OutputStream os = socket.getOutputStream();		
		//创建文件输出流(将上传的照片保存到本地)
		FileOutputStream fos = new FileOutputStream("E:\\smile.jpg");	
		byte[] bytes=new byte[1024]; 
		int len=0;	
		while((len=is.read(bytes))!=-1) {
			fos.write(bytes, 0, len);
			fos.flush();
			//只有文件才有EOF默认结束标志,
			//并且EOF默认值为-1,所以可以判断是否为结束标志
			//所以,当读取的数据没在文件中存储时,
			//不会读取到-1值,其len表示的是读取长度,恒大于0不能作为循条件
			if (len<1024) {	//最后一段数据
				break;
			}
		}		
		//反馈给客户端信息
		os.write("你好客户端,我已经收到您上传的照片".getBytes());		
		//关流
		fos.close();
		is.close();
		os.close();		
	}
}

2.UDP编程

  • 简介: UDP协议是一种不可靠的网络协议,提供面向事务的简单不可靠信息传送服务,每个包的大小64KB,速率快
    注意: 分为接收端与发送端

开发步骤:

  • 发送端:
    1.创建发送端的Socket对象(DatagramSocket)
    2.创建数据,并打包
    3.调用DatagramSocket对象的方法发送数据
    4.关闭发送端
  • 接收端:
    1、创建接收端的Socket对象(DatagramSocket)
    2、创建一个数据包,用于接收数据
    3、调用DatagramSocket对象的方法接收数据
    4、解析数据包,并在控制台显示
    5、关闭接收端
文件传输

1.接收端:

import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    public class UdpGet {
        public static void main(String[] args) throws IOException {
            //1,创建接收端Socket
            DatagramSocket socket = new DatagramSocket(9999);
            //2,创建接收数据的包
            byte[] b = new byte[1024];
            DatagramPacket packet = new DatagramPacket(b, b.length);
            //3,等待接收数据
            socket.receive(packet);
            //4,获取数据
            byte[] data = packet.getData();
            //5,获取数据长度
            int length = packet.getLength();
            //6,打印输出
            System.out.println("接收的内容:"+new String(data,0,length));
            //7,关闭资源
            socket.close();
        }
    }

2.发送端:

import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    public class UdpSend {
        public static void main(String[] args) throws IOException {
            //1,创建发送端Socket对象
            DatagramSocket socket = new DatagramSocket();
            //2,准备发送内容
            byte[] sendData = "要发送的内容".getBytes();
            //3,接收端地址
            InetAddress address = InetAddress.getByName(接收端的IP);
            //4,封装发送信息包
            DatagramPacket packet = new DatagramPacket(sendData,sendData.length, address, 9999);
            //5,发送信息
            socket.send(packet);
            //6,关闭发送端
            socket.close();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值