TCP和UDP C#代码实战

网络传输的七层结构:
在这里插入图片描述

其中TCP和UDP协议在传输层。

TCP/IP协议

TCP/IP中包含了四层架构中的多个协议,取其中两个进行了命名:
在这里插入图片描述

TCP

TCP的特点
在这里插入图片描述

粘包问题处理

TCP一次性接收过多数据必然出现粘包,即不同时发送的数据黏连在一起成为一个包,这是TCP的打包机制决定的。
处理粘包问题的方法是发送时在每一个数据前加上固定长度的包头,例如两个字节,表示数据的长度,在接收时按照长度把包一一解出来。解包的过程中有可能最后一个包的数据长度比包头显示的长度短或包头不完整,这是因为拆分成了两个包发送,只需将最后一个包的数据缓存,然后拼到下一个包的头部即可。

代码
客户端
using UnityEngine;
using System;
using System.Net;
using System.Net.Sockets; 
using System.Threading; public class MyTcp
{private static MyTcp singleInstance;private static readonly object padlock = new object();private byte[] result = new byte[1024];private Socket clientSocket;public bool isRun = false;private Action<bool> ac_connect;public static MyTcp Instance{get{lock (padlock)  // 加锁保证单例唯一{if (singleInstance == null){singleInstance = new MyTcp();}return singleInstance;}}}public void ConnectServer(string _ip, Action<bool> _result){//设定服务器IP地址  ac_connect = _result;IPAddress ip;bool _isRight = IPAddress.TryParse(_ip, out ip);if (!_isRight){Debug.Log("无效地址......" + _ip);_result(false);return;}clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPEndPoint _endpoint = new IPEndPoint(ip, 13001);Debug.Log("开始连接tcp~");clientSocket.BeginConnect(_endpoint, requestConnectCallBack, clientSocket);}private void requestConnectCallBack(IAsyncResult iar){try{//还原原始的TcpClient对象Socket client = (Socket)iar.AsyncState; client.EndConnect(iar);Debug.Log("连接服务器成功:" + client.RemoteEndPoint.ToString());isRun = true;ac_connect(true);}catch (Exception e){ac_connect(false);Debug.Log("tcp连接异常:" + e.Message);}finally{}}public void SendMessage(byte[] _mes){if (isRun){try{clientSocket.Send(_mes);}catch (Exception ex){EndClient();Debug.Log("发送数据异常:" + ex.Message);}}}public void EndClient(){isRun = false;if (clientSocket != null){try{clientSocket.Close();clientSocket = null;Debug.Log("关闭tcp连接");}catch (Exception ex){Debug.Log("关闭tcp连接异常111:" + ex.Message);}}}
}

主程序

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;public class Client : MonoBehaviour {// Use this for initializationvoid Start () {string _ip = "192.168.1.18";MyTcp.Instance.ConnectServer(_ip, (_result) => {if (_result){Debug.Log("连接成功"); string data = "aaaabbbbcccc";byte[] packheadByte = BitConverter.GetBytes((short)data.Length);byte[] message = System.Text.Encoding.UTF8.GetBytes(data);List<byte> sendMessage = new List<byte>();包头信息sendMessage.AddRange(packheadByte);sendMessage.AddRange(message);for (int i = 0; i < 100; i++){MyTcp.Instance.SendMessage(sendMessage.ToArray());}}else{Debug.Log("连接失败"); }}); }void OnApplicationQuit(){ MyTcp.Instance.EndClient(); }}
服务器
using UnityEngine;
using System.Collections.Generic;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Linq;public class ServerTcp {static Socket serverSocket;  private bool isRun = false;private Dictionary<string,Socket> dic_clientSocket = new Dictionary<string, Socket>();private static readonly object stLockObj = new object ();private static ServerTcp instance;int headSize = 2;//包头长度 固定2byte[] saveBuffer = null;//不完整的数据包,即用户自定义缓冲区public static ServerTcp Instance{get{ lock (stLockObj) {if (instance == null){instance = new ServerTcp();}	}return instance;}}private ServerTcp(){}public void Destory(){instance = null;}public void StartServer(){try {IPAddress ip = IPAddress.Parse("192.168.1.18");serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  serverSocket.Bind(new IPEndPoint(ip, 13001));  //绑定IP地址:端口  serverSocket.Listen(1000);    //设定最多10个排队连接请求  Debug.Log("启动监听" + serverSocket.LocalEndPoint.ToString() + "成功");isRun = true;//通过Clientsoket发送数据  Thread myThread = new Thread(ListenClientConnect);  myThread.Start();  	} catch (Exception ex) {Debug.Log ("服务器启动失败:" + ex.Message);}    }private void ListenClientConnect()  {  while (isRun)  {  try {Socket clientSocket = serverSocket.Accept();   Thread receiveThread = new Thread(ReceiveMessage);  receiveThread.Start(clientSocket);  	} catch (Exception ex) {Debug.Log ("监听失败:" + ex.Message);}}  }//				clientSocket.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null);public void EndServer(){if (!isRun) {return;}isRun = false;try {foreach (var item in dic_clientSocket) {item.Value.Close ();}dic_clientSocket.Clear ();if (serverSocket != null) {serverSocket.Close ();serverSocket = null;	}	} catch (Exception ex) {Debug.Log("tcp服务器关闭失败:" + ex.Message);}}public void CloseClientTcp(string _socketIp){try {if (dic_clientSocket.ContainsKey(_socketIp)) {if (dic_clientSocket [_socketIp] != null) {dic_clientSocket [_socketIp].Close();}dic_clientSocket.Remove (_socketIp);}	} catch (Exception ex) {Debug.Log ("关闭客户端..." + ex.Message);}}public int GetClientCount(){return dic_clientSocket.Count;}public List<string> GetAllClientIp(){return new List<string> (dic_clientSocket.Keys);}private void ReceiveMessage(object clientSocket)  {  Socket myClientSocket = (Socket)clientSocket;//  Debug.Log(myClientSocket.RemoteEndPoint.ToString());string _socketIp = myClientSocket.RemoteEndPoint.ToString().Split(':')[0]; Debug.Log ("有客户端连接:" + _socketIp);dic_clientSocket[_socketIp] = myClientSocket;	bool _flag = true;byte[] resultData = new byte[1048];while (isRun && _flag)  {  try  {  Debug.Log("_socketName是否连接:" + myClientSocket.Connected);int _size = myClientSocket.Receive(resultData);   if (_size <= 0) {throw new Exception("客户端关闭了222~");}		OnReceive(0, resultData);}catch (Exception ex)  {  Debug.Log(_socketIp + "接收客户端数据异常: " + ex.Message);  _flag = false;break;  }  }  CloseClientTcp (_socketIp);}  public void SendMessage(string _socketName,byte[] _mes){Debug.Log("SendMessage aaa  ----- _socketName  " + _socketName); if (isRun) {try {dic_clientSocket [_socketName].Send (_mes);	} catch (Exception ex) {Debug.Log ("发数据给异常:" + ex.Message);}	}}private bool OnReceive(int connId, byte[] bytes){// 系统缓冲区长度int bytesRead = bytes.Length;if (bytesRead > 0){if (saveBuffer == null)//第一次接收saveBuffer = bytes;//把系统缓冲区数据放在自定义缓冲区里面elsesaveBuffer = saveBuffer.Concat(bytes).ToArray();//拼接上次尾包int haveRead = 0;         //已经完成读取的数据包长度int totalLen = saveBuffer.Length; //这里totalLen的长度有可能大于缓冲区大小的(因为 这里的saveBuffer 是系统缓冲区+不完整的数据包)while (haveRead <= totalLen){//如果在N次拆解后剩余的数据包 小于 包头的长度 //则剩下的是非完整的数据包if (totalLen - haveRead < headSize){byte[] byteSub = new byte[totalLen - haveRead];//把剩下不够一个完整的数据包存起来Buffer.BlockCopy(saveBuffer, haveRead, byteSub, 0, totalLen - haveRead);saveBuffer = byteSub;totalLen = 0;break;}//如果够了一个完整包,则读取包头的数据byte[] headByte = new byte[headSize];Buffer.BlockCopy(saveBuffer, haveRead, headByte, 0, headSize);//从缓冲区里读取包头的字节int bodySize = BitConverter.ToInt16(headByte, 0);//从包头里面分析出包体的长度//这里的 haveRead=等于N个数据包的长度 从0开始;0,1,2,3....N//如果自定义缓冲区拆解N个包后的长度 大于 总长度,说最后一段数据不够一个完整的包了,拆出来保存if (haveRead + headSize + bodySize > totalLen){byte[] byteSub = new byte[totalLen - haveRead];Buffer.BlockCopy(saveBuffer, haveRead, byteSub, 0, totalLen - haveRead);saveBuffer = byteSub;break;}else{if (bodySize == 0){ saveBuffer = null;break;}//挨个分解每个包,解析成实际文字 String strc = Encoding.UTF8.GetString(saveBuffer, haveRead + headSize, bodySize);Debug.Log("得到包"  + strc); //依次累加当前的数据包的长度haveRead = haveRead + headSize + bodySize;if (headSize + bodySize == bytesRead)//如果当前接收的数据包长度正好等于缓冲区长度,则待拼接的不规则数据长度归0{saveBuffer = null;//设置空 回到原始状态totalLen = 0;//清0}}}}return true;}
}

UDP

UDP的特点
在这里插入图片描述

代码
客户端
using UnityEngine;
using System;
using System.Text;
using System.Threading;using System.Net;
using System.Net.Sockets;public class MyUdp {  private UdpClient sendClient = null;//	private IPEndPoint sendEndPort;private bool isRun;private bool isRecv;public void StartClientUdp(string _ip){//		if (sendEndPort != null) {//			Debug.Log ("客户端udp已经启动~");//			return;//		}if (isRun) {Debug.Log ("客户端udp已经启动~");return;}isRun = true;sendClient = UdpManager.Instance.GetClient();//		sendEndPort = new IPEndPoint(IPAddress.Parse(_ip), NetConfig.UdpSendPort);//	StartRecvMessage ();}private void StartRecvMessage(){Thread t = new Thread(new ThreadStart(RecvThread));t.Start();}public void StopRecvMessage(){isRecv = false;}public void EndClientUdp(){try {isRun = false;isRecv = false;//			if (sendEndPort != null) {//				UdpManager.Instance.CloseUdpClient();//				sendClient = null;//				sendEndPort = null;//			}UdpManager.Instance.CloseUdpClient();sendClient = null; 	} catch (Exception ex) {Debug.Log ("udp连接关闭异常:" + ex.Message);}}public void SendMessage(byte[] _mes){if (isRun) {try {sendClient.Send(_mes,_mes.Length); } catch (Exception ex) {Debug.Log ("udp发送失败:" + ex.Message);}}	}private void RecvThread(){isRecv = true;IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.169.1.18"), UdpManager.Instance.localPort);while (isRecv){try {byte[] buf = sendClient.Receive(ref endpoint);//				Debug.Log("发送量:" + buf.Length.ToString() + "," + GameData.Instance().recvNum.ToString());} catch (Exception ex) {Debug.Log ("udpClient接收数据异常:" + ex.Message);}}Debug.Log ("udp接收线程退出~~~~~");}void OnDestroy(){EndClientUdp ();}
}
using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;public class UdpManager {private static UdpManager singleInstance;private static readonly object padlock = new object();public UdpClient _udpClient = null;public int localPort;public static UdpManager Instance{get{lock (padlock){if (singleInstance==null){singleInstance = new UdpManager();}return singleInstance;}}}private UdpManager(){CreatUpd ();}public void Creat(){}void CreatUpd(){_udpClient = new UdpClient ();Debug.Log("CreatUpd   "  + localPort);IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("192.168.1.18"), 10011);_udpClient.Connect (endpoint);IPEndPoint _localEnd = (IPEndPoint)_udpClient.Client.LocalEndPoint;localPort = _localEnd.Port;Debug.Log ("udp参数:" + _localEnd.Address + "," + _localEnd.Port);}public void Destory(){CloseUdpClient ();singleInstance = null;}public void CloseUdpClient(){if (_udpClient != null) {_udpClient.Close ();_udpClient = null;}}public UdpClient GetClient(){if (_udpClient == null) {CreatUpd ();}return _udpClient;}}

主程序

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Uclient : MonoBehaviour {private MyUdp _upd;// Use this for initializationvoid Start () {StartClientUdp();}public void StartClientUdp(){_upd = new MyUdp();_upd.StartClientUdp("192.168.1.18");string data = "aaaabbbbcccc";byte[] message = System.Text.Encoding.UTF8.GetBytes(data);for (int i =0; i<20;i++){_upd.SendMessage(message);}}}
服务器
using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System;
public class UdpManager {private static UdpManager singleInstance;private static readonly object padlock = new object();public UdpClient _udpClient = null;public int recvPort;public static UdpManager Instance{get{lock (padlock){if (singleInstance==null){singleInstance = new UdpManager();}return singleInstance;}}}private UdpManager(){CreatUdp ();}public void Creat(){}void CreatUdp(){_udpClient = new UdpClient (10011);   // uint IOC_IN = 0x80000000;// uint IOC_VENDOR = 0x18000000;// uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;//byte[] optionOutValue = new byte[4];//byte[] optionInValue = { Convert.ToByte(false) };//_udpClient.Client.IOControl((int)SIO_UDP_CONNRESET, optionInValue, optionOutValue);IPEndPoint _localip = (IPEndPoint)_udpClient.Client.LocalEndPoint;Debug.Log ("udp端口:" + _localip.Port);recvPort = _localip.Port;}public void Destory(){CloseUdpClient ();singleInstance = null;}public void CloseUdpClient(){if (_udpClient != null) {Debug.Log("CloseUdpClient  **************** ");_udpClient.Close ();_udpClient = null;}}public UdpClient GetClient(){if (_udpClient == null) {CreatUdp ();}return _udpClient;}}

主程序:

using UnityEngine;
using System;
using System.Text;
using System.Threading;using System.Net;
using System.Net.Sockets;public class ClientUdp {public int userUid;private int sendPortNum;private UdpClient sendClient = null;private IPEndPoint sendEndPort;private bool isRun;private string serverIp;public void StartClientUdp(string _ip,int _uid){if (sendEndPort != null) {Debug.Log ("客户端udp已经启动~");return;}userUid = _uid;serverIp = _ip;isRun = true;sendClient = UdpManager.Instance.GetClient();//		sendClient = new UdpClient(NormalData.recvPort);//		sendEndPort = new IPEndPoint(IPAddress.Parse(_ip), ServerConfig.udpRecvPort);	Thread t = new Thread(new ThreadStart(RecvThread));t.Start();}public void EndClientUdp(){try {isRun = false;UdpManager.Instance.CloseUdpClient();sendClient = null;sendEndPort = null;} catch (Exception ex) {Debug.Log ("udp连接关闭异常:" + ex.Message);}}private void CreatSendEndPort(int _port){sendEndPort = new IPEndPoint(IPAddress.Parse(serverIp), _port);}public void SendMessage(byte[] _mes){if (isRun) {try {sendClient.Send (_mes,_mes.Length,sendEndPort);	//				GameData.Instance().sendNum+=_mes.Length;//				Debug.Log("发送量:" + _mes.Length.ToString() + "," + GameData.Instance().sendNum.ToString());} catch (Exception ex) {Debug.Log ("udp发送失败:" + ex.Message);}}}public void RecvClientReady(int _userUid){ if (_userUid == userUid && sendEndPort == null) {CreatSendEndPort(sendPortNum);}}// 接收线程不断 监听客户端的消息private void RecvThread(){IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse(serverIp), UdpManager.Instance.recvPort);while (isRun){try {byte[] buf = sendClient.Receive(ref endpoint);if (sendEndPort == null) {//Debug.Log("接收客户端udp信息:" + endpoint.Port);sendPortNum = endpoint.Port;}string str = System.Text.Encoding.UTF8.GetString(buf);Debug.Log("str *** " + str);//byte packMessageId = buf[PackageConstant.PackMessageIdOffset];     //消息id (1个字节)//Int16 packlength = BitConverter.ToInt16(buf,PackageConstant.PacklengthOffset);  //消息包长度 (2个字节)//int bodyDataLenth = packlength - PackageConstant.PacketHeadLength;//byte[] bodyData = new byte[bodyDataLenth];//Array.Copy(buf, PackageConstant.PacketHeadLength, bodyData, 0, bodyDataLenth);//delegate_analyze_message((PBCommon.CSID)packMessageId,bodyData);//是客户端,统计接收量//				GameData.Instance().recvNum+=buf.Length;//				Debug.Log("发送量:" + buf.Length.ToString() + "," + GameData.Instance().recvNum.ToString());} catch (Exception ex) {Debug.Log (endpoint.Address+ "udpClient接收数据异常:" + ex.Message);}}Debug.Log ("udp接收线程退出~~~~~");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/142074.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue2项目从0搭建(一):项目搭建

前言: vue2项目可谓十分常见,国内大部分的前端码农应该都是用vue2技术在开发,虽然vue3和react等技术也有很多,但是占据绝大多数的中高级搬砖码农应该干的都是vue2技术的项目,就算现在很多人转战vue3技术了,但是维护原有vue2的项目应该也是很多的。 我本来是不打算写vue2的技术…

Java17新增特性

前言 前面的文章&#xff0c;我们对Java9、Java10、Java11、Java12 、Java13、Java14、Java15、Java16 的特性进行了介绍&#xff0c;对应的文章如下 Java9新增特性 Java10新增特性 Java11新增特性 Java12新增特性 Java13新增特性 Java14新增特性 Java15新增特性 Java16新增特…

Clickhouse学习笔记(14)—— Clickhouse监控

ClickHouse 运行时会将一些个自身的运行状态记录到众多系统表中&#xff0c;如下所示&#xff1a; 为了直观方便地监控ck的运行情况&#xff0c;使用Prometheus Grafana 的组合来进行监控 Prometheus 负责收集各类系统的运行指标&#xff1b;Grafana 负责可视化 Prometheus&a…

实体门店创新神器曝光,拓世法宝AI智能直播一体机助力商家快速惊艳逆袭

在这个飞速变革的时代&#xff0c;传统实体门店面临着多重挑战。为了迎接市场的巨大变化&#xff0c;许多实体门店迫切寻求创新的方法来吸引顾客的眼球。数字化手段和新技术的引入成为实体门店应对市场需求的重要选择之一&#xff0c;是应对激烈竞争和不断变化的消费者行为的有…

WGCLOUD的特点整理

做运维工作很多年了&#xff0c;项目中用过不少的运维软件工具&#xff0c;今天整理下WGCLOUD的特点&#xff08;优点&#xff09; 首先WGCLOUD是完全免费的 部署使用&#xff1a;部署简单方便&#xff0c;上手容易&#xff0c;几乎没有学习成本&#xff0c;对新手友好 文档…

thinkphp 自定义错误页面

在访问无效的UI 这个效果不好&#xff0c;要改成自定义的 <?php namespace app\controller;class ErrorController {public function __call($method,$args){return error request!;} }之后就是提示

hive更改表结构的时候报错

现象 FAILED: ParseException line 1:48 cannot recognize input near ADD COLUMN compete_company_id in alter table statement 23/11/14 17:59:27 ERROR org.apache.hadoop.hive.ql.Driver: FAILED: ParseException line 1:48 cannot recognize input near ADD COLUMN compe…

upload-labs关卡8(基于黑名单的点绕过)通关思路

文章目录 前言一、回顾上一关知识点二、靶场第八关通关思路1、看源代码2、点绕过3、验证文件是否成功上传 总结 前言 此文章只用于学习和反思巩固文件上传漏洞知识&#xff0c;禁止用于做非法攻击。注意靶场是可以练习的平台&#xff0c;不能随意去尚未授权的网站做渗透测试&am…

计算机毕业设计选题推荐-记录生活微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

跨国企业如何选择安全靠谱的跨国传输文件软件?

随着全球化的不断发展&#xff0c;跨国企业之间的合作变得越来越频繁。而在这种合作中&#xff0c;如何安全、可靠地将文件传输给合作伙伴或客户&#xff0c;成为了跨国企业必须面对的问题。 然而&#xff0c;跨国文件传输并不是一件容易的事情&#xff0c;由于网络物理条件的…

什么是代理模式,用 Python 如何实现 Proxy(代理 或 Surrogate)对象结构型模式?

什么是代理模式&#xff1f; 代理&#xff08;Proxy&#xff09;是一种结构型设计模式&#xff0c;其目的是通过引入一个代理对象来控制对另一个对象的访问。代理对象充当目标对象的接口&#xff0c;这样客户端就可以通过代理对象间接地访问目标对象&#xff0c;从而在访问过程…

【Python图像超分】Real-ESRGAN图像超分模型(超分辨率重建)详细安装和使用教程

1 前言 图像超分是一种图像处理技术&#xff0c;旨在提高图像的分辨率&#xff0c;使其具有更高的清晰度和细节。这一技术通常用于图像重建、图像恢复、图像增强等领域&#xff0c;可以帮助我们更好地理解和利用图像信息。图像超分技术可以通过多种方法实现&#xff0c;包括插值…

CSS 文字溢出省略号显示

1. 单行文本溢出显示省略号 需要满足三个条件&#xff0c;添加对应的代码&#xff1a; &#xff08;1&#xff09;先强制一行内显示文本&#xff1b; &#xff08;2&#xff09;超出的部分隐藏&#xff1b; &#xff08;3&#xff09;文字用省略号来替代省略的部分&#xf…

IDEA 使用Reset Current Branch to Here 进行git 版本控制,图文操作

文章目录 一、总结区别&#xff08;只针对本地仓库操作&#xff09;Soft详细解释文件版本冲突处理 Mixed详细解释Hard详细解释Keep详细解释文件版本冲突处理 二、其他Revert commit 参考文档 一、总结区别&#xff08;只针对本地仓库操作&#xff09; Soft详细解释 Soft操作只…

docker命令大全

1、查看Docker 容器占用的空间 docker ps -s2、查看所有容器 docker ps -a3、启动、关闭、重启一个已存在的容器 docker start <容器ID> docker stop <容器ID> docker restart <容器ID> 4、进入容器&#xff0c;退出终端的时候不会关闭container的ma…

龙讯旷腾PWmat:新的催化反应机理——瞬态相变,对多相电催化剂的设计和多相电催化机理的研究具有重要意义

研究背景 众所周知&#xff0c;材料的性质&#xff0c;包括催化活性都是相敏感的。而材料的相与外界条件有关&#xff0c;电催化反应过程中的外部条件与反应前后的外部条件不同&#xff0c;这自然导致了一个问题&#xff1a;在反应过程中电催化剂的相是否可以与反应前后的相不…

C 语言数组

C 语言数组 在本教程中&#xff0c;您将学习如何使用数组。您将借助示例学习如何声明&#xff0c;初始化和访问数组的元素。 数组是可以存储多个值的变量。例如&#xff0c;如果要存储100个整数&#xff0c;则可以为其创建一个数组。 示例 cint data[100];如何声明数组&…

线程池的使用

线程池的作用 降低线程创建和销毁的开销&#xff1a;线程的创建和销毁是比较昂贵的操作。通过使用线程池&#xff0c;可以避免频繁地创建和销毁线程&#xff0c;而是复用线程池中已经存在的线程&#xff0c;从而降低了开销。 控制并发度&#xff1a;通过控制线程池中线程的数量…

MySQL(14):视图

数据库对象 对象描述表(TABLE)表是存储数据的逻辑单元&#xff0c;以行和列的形式存在&#xff0c;列就是字段&#xff0c;行就是记录数据字典就是系统表&#xff0c;存放数据库相关信息的表。系统表的数据通常由数据库系统维护&#xff0c;程序员通常不应该修改&#xff0c;只…

mysql 讲解(1)

文章目录 前言一、基本的命令行操作二、操作数据库语句2.1、创建数据库2.2、删除数据库2.3、使用数据库2.4 查看所有数据库 三、列的数据类型3.1 字符串3.2 数值3.3 时间日期3.4 空3.5 int 和 varchar问题总结&#xff1a; 四、字段属性4.1 UnSigned4.2 ZEROFILL4.3 Auto_InCre…