u3d下的Tcp和Udp通訊的兩種寫法
阿新 • • 發佈:2019-02-05
1、使用Socket的Tcp
服務端:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System; public class ScocketServer : MonoBehaviour { private Thread _StartServer; byte[] byte_receive; Socket RecieveSocket; IPEndPoint iep; EndPoint ep; // Use this for initialization void Start () { //Socket Tcp byte_receive = new byte[100]; iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1001); RecieveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); RecieveSocket.Bind(iep); RecieveSocket.Listen(10); _StartServer = new Thread(StartServer); _StartServer.Start(); } // Update is called once per frame void Update () { } void StartServer() { Debug.Log("服務端:等人..."); Socket tempSocket = RecieveSocket.Accept();//阻斷 Debug.Log("服務端:有人來了"); while (true) { int datalength = tempSocket.Receive(byte_receive); if (datalength != 0) { string msg = Encoding.Unicode.GetString(byte_receive); Debug.Log("服務端:我收到訊息:" + msg); } } } private void OnApplicationQuit() { if (_StartServer != null)//關閉執行緒 { _StartServer.Interrupt(); _StartServer.Abort(); } //最後關閉socket if (RecieveSocket != null) RecieveSocket.Close(); } }
客戶端:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net; using System.Net.Sockets; using System.Text; using System; using System.Threading; public class ScocketClient : MonoBehaviour { private Thread ClientThread; int MsgIndex; Socket ClientSocket; IPEndPoint ep; string msg; byte[] byteSendingArray; // Use this for initialization void Start () { ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1001); byteSendingArray = new byte[100]; MsgIndex = 0; } // Update is called once per frame void Update () { if(Input.GetKeyDown(KeyCode.Alpha1)) { SendMsg(); } } private void SendMsg() { try { if(ClientSocket == null) { ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ClientSocket.Connect(IPAddress.Parse("127.0.0.1"), 1001); ClientSocket.Receive(byteSendingArray); Debug.Log(Encoding.Unicode.GetString(byteSendingArray)); } msg = "客戶端:啊~~~" + MsgIndex + "環"; byteSendingArray = Encoding.Unicode.GetBytes(msg); ClientSocket.Send(byteSendingArray); } catch (Exception ex) { Debug.Log(ex.Message); } MsgIndex++; } }
2、使用Socket的Udp
服務端:
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System; public class ScocketServer : MonoBehaviour { private Thread _StartServer; byte[] byte_receive; Socket RecieveSocket; IPEndPoint iep; EndPoint ep; // Use this for initialization void Start () { //Socket Udp byte_receive = new byte[100]; iep = new IPEndPoint(IPAddress.Any, 1001); RecieveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); RecieveSocket.Bind(iep); ep = (EndPoint)iep; _StartServer = new Thread(StartServer); _StartServer.Start(); } // Update is called once per frame void Update () { } void StartServer() { //Socket Udp while (true) { int intReceiveLength = RecieveSocket.ReceiveFrom(byte_receive, ref ep); string strReceiveStr = Encoding.Unicode.GetString(byte_receive, 0, intReceiveLength); Debug.Log("收到訊息: " + strReceiveStr); } } private void OnApplicationQuit() { if (_StartServer != null) { _StartServer.Interrupt(); _StartServer.Abort(); } //最後關閉socket if (RecieveSocket != null) RecieveSocket.Close(); } }
客戶端:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;
public class ScocketClient : MonoBehaviour {
TcpClient MyClient;
private Thread ClientThread;
int MsgIndex;
Socket ClientSocket;
IPEndPoint ep;
string msg;
byte[] byteSendingArray;
// Use this for initialization
void Start () {
ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1001);
byteSendingArray = new byte[100];MsgIndex = 0;
ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.Alpha1))
{
SendMsg();
}
}
private void SendMsg()
{
try
{
//Socket Udp
msg = "客戶端:啊~~~" + MsgIndex + "環";
byteSendingArray = Encoding.Unicode.GetBytes(msg);
ClientSocket.SendTo(byteSendingArray,ep);
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
MsgIndex++;
}
}
3、不使用Socket的Tcp
服務端:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
public class ScocketServer : MonoBehaviour {
private Thread _StartServer;
byte[] byte_receive;
Socket RecieveSocket;
IPEndPoint iep;
EndPoint ep;
// Use this for initialization
void Start () {
_StartServer = new Thread(StartServer);
_StartServer.Start();
}
// Update is called once per frame
void Update () {
}
void StartServer()
{
//tcp-----------------------------
const int MyBuffSize = 1024;
IPAddress ServerIP = IPAddress.Parse("127.0.0.1");
TcpListener myListener = new TcpListener(ServerIP, 10001);
myListener.Start();
Debug.Log("伺服器監聽,啟動!!");
TcpClient remoteClient = myListener.AcceptTcpClient(); //阻塞
Debug.Log("有客到!");
NetworkStream ClientStream = remoteClient.GetStream();
byte[] buffer = new byte[MyBuffSize];
do
{
try
{
int byteRead = ClientStream.Read(buffer, 0, MyBuffSize);
if (byteRead == 0)
{
Debug.Log("沒東西啊!!");
continue;
}
string msg = Encoding.Unicode.GetString(buffer, 0, byteRead);
Debug.Log("接收資料:" + msg);
}
catch (Exception ex)
{
Debug.Log("異常:" + ex.Message);
break;
}
}
while (true);
}
private void OnApplicationQuit()
{
if (_StartServer != null)
{
_StartServer.Interrupt();
_StartServer.Abort();
}
}
}
客戶端:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;
public class ScocketClient : MonoBehaviour {
TcpClient MyClient;
private Thread ClientThread;
int MsgIndex;
Socket ClientSocket;
IPEndPoint ep;
string msg;
byte[] byteSendingArray;
// Use this for initialization
void Start () {
//tcp-------------------------------
MsgIndex = 0;
MyClient = new TcpClient();
try
{
MyClient.Connect(IPAddress.Parse("127.0.0.1"), 10001);
}
catch (Exception ex)
{
Debug.Log("客戶端連線異常:" + ex.Message);
}
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.Alpha1))
{
SendMsg();
}
}
private void SendMsg()
{
//tcp---------------------------------
try
{
string msg = "我是訊息 " + MsgIndex;
NetworkStream streamToServer = MyClient.GetStream();//獲得客戶端的流
byte[] buffer = Encoding.Unicode.GetBytes(msg);//將字串轉化為二進位制
streamToServer.Write(buffer, 0, buffer.Length);//將轉換好的二進位制資料寫入流中併發送
Debug.Log("發出訊息:" + msg);
}
catch (Exception ex)
{
Debug.Log("異常:" + ex.Message);
}
MsgIndex++;
}
}
4、不使用Socket的Udp
服務端:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
public class ScocketServer : MonoBehaviour {
private Thread _StartServer;
UdpClient MyUdpClient;
// Use this for initialization
void Start () {
_StartServer = new Thread(StartServer);
_StartServer.Start();
}
void StartServer()
{
//udp-----------------------------
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 1234);
MyUdpClient = new UdpClient(10001);
while (true)
{
byte[] data = MyUdpClient.Receive(ref anyIP);
string msg = Encoding.Unicode.GetString(data);
Debug.Log("收到訊息:" + msg);
}
}
private void OnApplicationQuit()
{
if (MyUdpClient != null)
MyUdpClient.Close();
if (_StartServer != null)
{
_StartServer.Interrupt();
_StartServer.Abort();
}
}
}
客戶端:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;
public class ScocketClient : MonoBehaviour {
UdpClient MyUdpClient;
int MsgIndex;
// Use this for initialization
void Start () {
ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10001);
MyUdpClient = new UdpClient();
MyUdpClient.Connect(ep);
}
// Update is called once per frame
void Update () {
if(Input.GetKeyDown(KeyCode.Alpha1))
{
SendMsg();
}
}
private void SendMsg()
{
//udp---------------------------------
string msg = "我是訊息 " + MsgIndex;
byte[] buffer = Encoding.Unicode.GetBytes(msg);
Debug.Log("發出訊息:" + msg);
MyUdpClient.Send(buffer, buffer.Length);
MsgIndex++;
}
private void OnApplicationQuit()
{
if (MyUdpClient != null)
MyUdpClient.Close();
}
}
其實說服務端客戶端還不如說接收端傳送端,Tcp和Udp都是傳輸層協議,是一套約定好的傳輸法則,不同的是,Tcp要建立連線才能傳輸,Udp則不需要。用屁股也想得到,需要建立連線的,肯定要安全一點,也肯定要慢一些,有優點自然有缺點嘛。(是不是有點像Durex,笑)
需要注意的點:
1、埠對應。
2、阻斷函式(執行緒)
3、記得釋放(貓兒拉屎貓兒埋)