소켓 전송 protobuf 바이트 스트림 도입 예
이전 글에서는 데이터 처리에 대해 이야기했지만 이번 글에서는 주로 멀티 스레드를 사용하여 메시지를 보내고 받는 것에 대해 설명합니다
//创建消息数据模型 2 //正式项目中,消息的结构一般是消息长度+消息id+消息主体内容 3 public class Message 4 { public IExtensible protobuf; public int messageId; 7 } 8 9 public class SocketClientTemp : MonoBehaviour 10 { 11 const int packageMaxLength = 1024; 12 13 Socket mSocket; 14 Thread threadSend; 15 Thread threadRecive; 16 Queue<Message> allMessages = new Queue<Message>(); 17 Queue<byte[]> sendQueue = new Queue<byte[]>(); public bool Init() 20 { 21 //创建一个socket对象 22 mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 23 return SocketConnection("此处是ip", 1111); 24 } 25 26 void Update() 27 { 28 AnalysisMessage(); 29 } 30 31 /// <summary> 32 /// 建立服务器连接 33 /// </summary> 34 /// <param name="ip">服务器的ip地址</param> 35 /// <param name="port">端口</param> 36 bool SocketConnection(string ip, int port) 37 { 38 try 39 { 40 IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), port); 41 //同步连接服务器,实际使用时推荐使用异步连接,处理方式会在下一篇讲断线重连时讲到 42 mSocket.Connect(ipep); 43 //连接成功后,创建两个线程,分别用于发送和接收消息 44 threadSend = new Thread(new ThreadStart(SendMessage)); 45 threadSend.Start(); 46 threadRecive = new Thread(new ThreadStart(ReceiveMessage)); 47 threadRecive.Start(); 48 return true; 49 } 50 catch (Exception e) 51 { 52 Debug.Log(e.ToString()); 53 Close(); 54 return false; 55 } } #region ...发送消息 59 /// <summary> 60 /// 添加数据到发送队列 61 /// </summary> 62 /// <param name="protobufModel"></param> 63 /// <param name="messageId"></param> 64 public void AddSendMessageQueue(IExtensible protobufModel, int messageId) 65 { 66 sendQueue.Enqueue(BuildPackage(protobufModel, messageId)); 67 } void SendMessage() 70 { 71 //循环获取发送队列中第一个数据,然后发送到服务器 72 while (true) 73 { 74 if (sendQueue.Count == 0) 75 { 76 Thread.Sleep(100); 77 continue; 78 } 79 if (!mSocket.Connected) 80 { 81 Close(); 82 break; 83 } 84 else 85 Send(sendQueue.Peek()); //发送队列中第一条数据 86 } 87 } 88 89 void Send(byte[] bytes) 90 { 91 try 92 { 93 mSocket.Send(bytes, SocketFlags.None); 94 //发送成功后,从发送队列中移除已发送的消息 95 sendQueue.Dequeue(); 96 } 97 catch (SocketException e) 98 { 99 //如果错误码为10035,说明服务器缓存区满了,所以等100毫秒再次发送100 if (e.NativeErrorCode == 10035)101 {102 Thread.Sleep(100);103 Send(bytes);104 }105 else106 Debug.Log(e.ToString());107 }108 }109 #endregion110 111 #region ...接收消息112 /// <summary>113 /// 解析收到的消息114 /// </summary>115 void AnalysisMessage()116 {117 while (allMessages.Count > 0)118 {119 int id = allMessages.Dequeue().messageId;120 switch (id)121 {122 //根据消息id做不同的处理123 }124 }125 }126 127 /// <summary>128 /// 接收数据129 /// </summary>130 void ReceiveMessage()131 {132 while (true)133 {134 if (!mSocket.Connected)135 break;136 byte[] recvBytesHead = GetBytesReceive(4);137 int bodyLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(recvBytesHead, 0));138 byte[] recvBytesBody = GetBytesReceive(bodyLength);139 140 byte[] messageId = new byte[4];141 Array.Copy(recvBytesBody, 0, messageId, 0, 4);142 byte[] messageBody = new byte[bodyLength - 4];143 Array.Copy(recvBytesBody, 4, messageBody, 0, bodyLength - 4);144 145 if (BitConverter.IsLittleEndian)146 Array.Reverse(messageId);147 FillAllPackages(BitConverter.ToInt32(messageId, 0), messageBody);148 } } /// <summary>152 /// 填充接收消息队列153 /// </summary>154 /// <param name="messageId"></param>155 /// <param name="messageBody"></param>156 void FillAllPackages(int messageId, byte[] messageBody)157 {158 switch (messageId)159 {160 //根据消息id处理消息,并添加到接收消息队列161 case 1:162 allMessages.Enqueue(new Message() 163 {164 protobuf = ProtobufSerilizer.DeSerialize<TestTemp>(messageBody), 165 messageId = messageId 166 });167 break;168 }169 }170 171 /// <summary>172 /// 接收数据并处理173 /// </summary>174 /// <param name="length"></param>175 /// <returns></returns>176 byte[] GetBytesReceive(int length)177 {178 byte[] recvBytes = new byte[length];179 while (length > 0)180 {181 byte[] receiveBytes = new byte[length < packageMaxLength ? length : packageMaxLength];182 int iBytesBody = 0;183 if (length >= receiveBytes.Length)184 iBytesBody = mSocket.Receive(receiveBytes, receiveBytes.Length, 0);185 else186 iBytesBody = mSocket.Receive(receiveBytes, length, 0);187 receiveBytes.CopyTo(recvBytes, recvBytes.Length - length);188 length -= iBytesBody;189 }190 return recvBytes;191 }192 #endregion193 194 /// <summary>195 /// 构建消息数据包196 /// </summary>197 /// <param name="protobufModel"></param>198 /// <param name="messageId"></param>199 byte[] BuildPackage(IExtensible protobufModel, int messageId)200 {201 byte[] b;202 if (protobufModel != null)203 b = ProtobufSerilizer.Serialize(protobufModel);204 else205 b = new byte[0];206 //消息长度(int数据,长度4) + 消息id(int数据,长度4) + 消息主体内容207 ByteBuffer buf = ByteBuffer.Allocate(b.Length + 4 + 4);208 //消息长度 = 消息主体内容长度 + 消息id长度209 buf.WriteInt(b.Length + 4);210 buf.WriteInt(messageId);211 212 if (protobufModel != null)213 buf.WriteBytes(b);214 return buf.GetBytes();215 }216 217 void OnDestroy()218 {219 //停止运行后,如果不关闭socket多线程,再次运行时,unity会卡死220 Close();221 }222 223 /// <summary>224 /// 关闭socket,终止线程225 /// </summary>226 public void Close()227 {228 if (mSocket != null)229 {230 //微软官方推荐在关闭socket前先shutdown,但是经过测试,发现网络断开后,shutdown会无法执行231 if (mSocket.Connected)232 mSocket.Shutdown(SocketShutdown.Both);233 mSocket.Close();234 mSocket = null;235 }236 //关闭线程237 if (threadSend != null)238 threadSend.Abort();239 if (threadRecive != null)240 threadRecive.Abort();241 threadSend = null;242 threadRecive = null;243 }244 }
이 시점에서 메시지 보내기 및 받기를 처리하기 위한 소켓 사용은 기본적으로 끝났습니다. 경험을 향상시키려면 일부 프로젝트에 연결 해제 및 재연결 기능을 추가할 수도 있습니다. 이 기능은 다음 기사에서 설명하겠습니다
위 내용은 소켓 전송 protobuf 바이트 스트림 도입 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











이 기사에서는 주로 IO 멀티플렉싱을 소개하는 php+socket과 php+socket이 웹 서버를 구현하는 방법에 대한 관련 지식을 제공합니다. 관심 있는 친구들은 아래를 살펴보시면 모두에게 도움이 되길 바랍니다.

1. TCP 프로토콜 기반 소켓 프로그래밍 1. 소켓 워크플로는 서버 측에서 시작됩니다. 서버는 먼저 소켓을 초기화한 다음 포트에 바인드하고 포트를 수신하며 차단을 위해 승인을 호출하고 클라이언트가 연결될 때까지 기다립니다. 이때 클라이언트가 Socket을 초기화한 후 서버에 연결(connect)하면, 연결에 성공하면 클라이언트와 서버 간의 연결이 성립된다. 클라이언트는 데이터 요청을 보내고, 서버는 요청을 받아 요청을 처리한 후 클라이언트에 응답 데이터를 보내고, 클라이언트는 데이터를 읽고 마지막으로 연결을 종료합니다. 이를 구현하려면 다음 Python 코드를 사용하세요. : importso

이 사이트는 유니티의 첫 제품인 유니티 엔진 제네시스 에디션(Unity Engine Genesis Edition)과 유니티 엔진 카 에디션(Unity Engine Car Edition)이 공식적으로 내부 테스트 활동을 시작했다고 10월 16일 보도했다. 개발자를 위한 내부 테스트. 테스트 시간: 2023년 10월 16일부터 2023년 12월 31일까지. 이 사이트에서는 Unity Engine이 Unity China R&D 팀에서 출시한 Unity의 중국어 버전임을 확인했습니다. Unity2022LTS를 기반으로 WeChat 미니 게임 솔루션과 Unity 엔진의 자동차 기계 버전을 출시했습니다. WeChat 미니 게임 솔루션 Unity 엔진은 WeChat 미니 게임 개발(환경 적응, 성능 최적화)을 더 효과적으로 지원하기 위해 WeChat 미니 게임 전용 목표를 추가했습니다.

SpringBoot 측의 첫 번째 단계는 종속성을 도입하는 것입니다. 먼저 WebSocket에 필요한 종속성과 com.alibabafastjson1.2.73org.springframework.bootspring-boot-starter-websocket 출력 형식을 처리하기 위한 종속성을 도입해야 합니다. 두 번째 단계는 WebSocket 구성 클래스 importorg를 생성하는 것입니다. springframework.context.annotation.Bean;importorg.springframework.context.annotation.Config

PHP 소켓을 연결할 수 없는 문제에 대한 해결책: 1. PHP에서 소켓 확장이 활성화되어 있는지 확인하십시오. 2. php.ini 파일을 열고 "php_sockets.dll"이 로드되었는지 확인하십시오. 3. "php_sockets.dll"의 주석을 제거하십시오. ".

인터넷이 발전하면서 파일 전송은 사람들의 일상 업무와 오락에 없어서는 안 될 부분이 되었습니다. 그러나 이메일 첨부나 파일 공유 웹사이트와 같은 기존 파일 전송 방법에는 특정 제한이 있으며 실시간 및 보안 요구 사항을 충족할 수 없습니다. 따라서 실시간 파일 전송을 달성하기 위해 PHP 및 소켓 기술을 사용하는 것이 새로운 솔루션이 되었습니다. 이 기사에서는 실시간 파일 전송을 달성하기 위해 PHP 및 소켓 기술을 사용하는 기술 원리, 장점 및 응용 시나리오를 소개하고 구체적인 사례를 통해 이 기술의 구현 방법을 보여줍니다. 기술

Unity3D 프로그램 코드의 보안 문제 보안 문제 Unity3D 프로그램의 핵심 어셈블리 파일 Assembly-CSharp.dll은 표준 .NET 파일 형식이며 메서드 이름, 클래스 이름, 유형 정의 등과 같은 풍부한 메타데이터 정보가 함께 제공됩니다. DnSpy와 같은 도구를 사용하면 쉽게 디컴파일 및 변조가 가능하며 코드 로직, 클래스 이름, 메소드 이름 등을 한눈에 볼 수 있습니다. 코드 로직이 디컴파일되면 다양한 유형의 플러그인이 번식하기 쉽고 게임의 밸런스가 파괴되기 쉽습니다. 코드 로직에 허점이 있으면 발견되어 악용되기 쉬우며 이로 인해 예측할 수 없는 손실이 발생할 수 있습니다. 개발자. 리소스 보안 문제: 컴파일 및 패키징 단계에서 Unity3D 프로그램은 Unity 편집기를 통해 리소스를 AssetBun으로 패키징합니다.

C#의 일반적인 네트워크 통신 및 보안 문제와 해결 방법 오늘날 인터넷 시대에 네트워크 통신은 소프트웨어 개발에 없어서는 안 될 부분이 되었습니다. C#에서는 일반적으로 데이터 전송 보안, 네트워크 연결 안정성 등과 같은 일부 네트워크 통신 문제가 발생합니다. 이 문서에서는 C#의 일반적인 네트워크 통신 및 보안 문제에 대해 자세히 설명하고 해당 솔루션과 코드 예제를 제공합니다. 1. 네트워크 통신 문제 네트워크 연결 중단: 네트워크 통신 과정에서 네트워크 연결이 중단될 수 있으며, 이로 인해
