知识点:
Tcp/Ip 四层模型
Socket相关概念
Socket的通讯过程
TCP代码
基础版客户端
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
public class SocketClient : MonoBehaviour
{
public InputField input;
//开始连接
public void StartClick()
{
bt_connect_Click();
}
public void SendMsg()
{
bt_send_Click(input.text);
}
Socket socketSend;
private void bt_connect_Click()
{
try
{
int _port = 6000;
string _ip = "x.x.x.x";
socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(_ip);
IPEndPoint point = new IPEndPoint(ip, _port);
socketSend.Connect(point);
Debug.Log("连接成功");
//开启新的线程,不停的接收服务器发来的消息
Thread c_thread = new Thread(Received);
c_thread.IsBackground = true;
c_thread.Start();
}
catch (Exception)
{
Debug.Log("IP或者端口号错误。。。");
}
}
/// <summary>
/// 接收服务端返回的消息
/// </summary>
void Received()
{
while (true)
{
try
{
byte[] buffer = new byte[1024 * 1024 * 3];
//实际接收到的有效字节数
int len = socketSend.Receive(buffer);
if (len == 0)
{
break;
}
string str = Encoding.UTF8.GetString(buffer, 0, len);
Debug.Log("客户端打印:" + socketSend.RemoteEndPoint + ":" + str);
}
catch { }
}
}
/// <summary>
/// 向服务器发送消息
/// </summary>
/// <param name="str"></param>
private void bt_send_Click(string str)
{
try
{
string msg = str;
byte[] buffer = new byte[1024 * 1024 * 3];
buffer = Encoding.UTF8.GetBytes(msg);
socketSend.Send(buffer);
}
catch { }
}
}
断线异步重连客户端
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.PackageManager;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine.UI;
public class AsyncTcpClient
{
private string ip1="x.x.x.x";
private int port1=6000;
byte[] ReadBytes = new byte[1024 * 1024*5];
public string str = "";
//单例
public static AsyncTcpClient Instance
{
get
{
if (instance == null)
{
instance = new AsyncTcpClient();
}
return instance;
}
}
private static AsyncTcpClient instance;
System.Net.Sockets.TcpClient tcpClient;
//连接服务器
public void ConnectServer(string ip, int port)//填写服务端IP与端口
{
//Debuger.EnableSave = true;
ip1 = ip;
port1 = port;
try
{
tcpClient = new System.Net.Sockets.TcpClient();//构造Socket
tcpClient.BeginConnect(IPAddress.Parse(ip), port, Lianjie, null);//开始异步
}
catch (Exception e)
{
Debug.Log(e.Message);
}
}
//连接判断
void Lianjie(IAsyncResult ar)
{
if (!tcpClient.Connected)
{
Debug.Log("服务器未开启,尝试重连。。。。。。");
tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null);
//IAsyncResult rest = tcpClient.BeginConnect(IPAddress.Parse(ip1), port1, Lianjie, null);
//bool scu= rest.AsyncWaitHandle.WaitOne(3000);
}
else
{
Debug.Log("连接上了");
tcpClient.EndConnect(ar);//结束异步连接
tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null);
}
}
//接收消息
void ReceiveCallBack(IAsyncResult ar)
{
try
{
int len = tcpClient.GetStream().EndRead(ar);//结束异步读取
if (len > 0)
{
str = Encoding.UTF8.GetString(ReadBytes, 0, len);
str = Uri.UnescapeDataString(str);
//将接收到的消息写入日志
// Debug.Log(string.Format("收到主机:{0}发来的消息|{1}", ip1, str));
Debug.Log(str);
tcpClient.GetStream().BeginRead(ReadBytes, 0, ReadBytes.Length, ReceiveCallBack, null);
}
else
{
tcpClient = null;
Debug.Log("连接断开,尝试重连。。。。。。");
ConnectServer(ip1, port1);
}
}
catch (Exception e)
{
Debug.Log(e.Message);
}
}
//发送消息
public void SendMsg(string msg)
{
byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
tcpClient.GetStream().BeginWrite(msgBytes, 0, msgBytes.Length, (ar) => {
tcpClient.GetStream().EndWrite(ar);//结束异步发送
}, null);//开始异步发送
}
/// <summary>
/// 断开连接
/// </summary>
public void Close()
{
if (tcpClient != null && tcpClient.Client.Connected)
tcpClient.Close();
if (!tcpClient.Client.Connected)
{
tcpClient.Close();//断开挂起的异步连接
}
}
}
参考: https://www.cnblogs.com/linkshow/p/12100929.html
测试脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class StartAsyncTcpClient : MonoBehaviour
{
private string ip1 = "10.2.10.149";
private int port1 = 6000;
public InputField input;
public Text textreceive;
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
AsyncTcpClient.Instance.ConnectServer(ip1, port1);
}
textreceive.text = AsyncTcpClient.Instance.str;
}
public void SendMsg()
{
AsyncTcpClient.Instance.SendMsg(input.text);
}
}
**
带Socket UDP发送端
**
using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine.UI;
public class UDPClient1 : MonoBehaviour
{
public string recvStr;
private string UDPClientIP;
Socket socket;
EndPoint serverEnd;
IPEndPoint ipEnd;
byte[] recvData = new byte[1024];
byte[] sendData = new byte[1024];
int recvLen = 0;
Thread connectThread1;
Thread connectThread2;
public InputField inputField;
public Text text;
void Start()
{
UDPClientIP = "10.2.10.149";//服务端的IP.自己更改
UDPClientIP = UDPClientIP.Trim();
InitSocket();
}
void InitSocket()
{
ipEnd = new IPEndPoint(IPAddress.Parse(UDPClientIP), 3456);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
serverEnd = (EndPoint)sender;
print("等待连接");
inputField.text = " ";
SocketSend();
print("连接");
//开启一个线程连接
connectThread1 = new Thread(new ThreadStart(SocketReceive));
connectThread1.Start();
connectThread2 = new Thread(new ThreadStart(SocketSend));
}
public void SocketSend()
{
string sendStr = inputField.text;
//清空
sendData = new byte[1024];
//数据转换
sendData = Encoding.UTF8.GetBytes(sendStr);
//发送给指定服务端
socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
}
//接收服务器信息
void SocketReceive()
{
while (true)
{
recvData = new byte[1024];
try
{
recvLen = socket.ReceiveFrom(recvData, ref serverEnd);
}
catch (Exception e)
{
}
print("信息来自: " + serverEnd.ToString());
if (recvLen > 0)
{
recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);
// text.text = recvStr;
print(recvStr);
}
}
}
//连接关闭
void SocketQuit()
{
//关闭线程
if (connectThread1 != null)
{
connectThread1.Interrupt();
connectThread1.Abort();
}
if (connectThread2 != null)
{
connectThread2.Interrupt();
connectThread2.Abort();
}
//最后关闭socket
if (socket != null)
socket.Close();
}
void OnApplicationQuit()
{
SocketQuit();
}
int i = 0;
}
不带Socket的发送端
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
/// <summary>
/// 发送脚本
/// </summary>
public class UDPClient1Msg : MonoBehaviour {
string sendString = null;//要发送的字符串
byte[] sendData = null;//要发送的字节数组
UdpClient client = null;
public static UDPClient1Msg Instance;
private void Awake()
{
Instance = this;
}
public void SendMsg(string sendStr)
{
IPAddress remoteIP = IPAddress.Parse("127.0.0.1"); //假设发送给这个IP
int remotePort = 9000;
IPEndPoint remotePoint = new IPEndPoint(remoteIP, remotePort);//实例化一个远程端点
if (sendStr != null)
{
sendData = Encoding.Default.GetBytes(sendStr);
client = new UdpClient();
client.Send(sendData, sendData.Length, remotePoint);//将数据发送到远程端点
client.Close();//关闭连接
sendString = null;
}
}
}