概述
记录在unity 网络连接中,对 socket UDP学习过程。
2020-7-15更新 前段时间需要写广播功能、、
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//初始化一个Scoket实习,采用UDP传输
IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 8888);
//初始化一个发送广播和指定端口的网络端口实例 就跟 IPAdress.Any 一样,可以接受任何ip发来的消息
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
//设置该scoket实例的发送形式
data = Encoding.ASCII.GetBytes(msg);
socket.SendTo(data, iep);
服务端
UDP服务端,绑定了固定端口,知道自己的固定IP。
using UnityEngine;
using System.Collections;
//引入库
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections.Generic;
public class UdpServer:MonoBehaviour
{
Socket socket; //定义一个socket
EndPoint clientEnd; //负责客户端参数
IPEndPoint ipEnd; //定义自身侦听端口
//IPEndPoint继承与EndPoint。IPEndPoint引用的时候参数为IP和端口。
//IPEndPoint iep = new IPEndPoint(IPAddress.Any, 9050);.net中 Bind(EndPoint localEP);方法参数是EndPoint,
//填入IPEndPoint会按照EndPoint参数执行。EndPoint是IPEndPoint的基类,
//IPEndPoint可以强转为EndPoint。EndPoint ep = (EndPoint)iep;
//主要目的是IPEndPoint可以自己写入IP地址和端口
string recvStr; //接收的字符串
string sendStr; //发送的字符串
byte[] recvData=new byte[1024]; //接收的数据,必须为字节
byte[] sendData=new byte[1024]; //发送的数据,必须为字节
int recvLen; //接收的数据长度
Thread connectThread; //定义线程
Queue<string> queue = new Queue<string>();//定义一个队列(先进先出)
// Use this for initialization
void Start()
{
InitSocket();
}
//初始化
void InitSocket()
{
//定义侦听端口,侦听任何IP
ipEnd=new IPEndPoint(IPAddress.Any,5555);
//定义socket
socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
//服务端定义端口
socket.Bind(ipEnd);
//定义客户端任何IP和端口(这里参数没啥意义,后面接收过程中会再次赋值,当然如果自己知道目标主机的IP和端口,这里倒是可以直接赋值,然后发送。这就变得跟下面客户端差不多了。只要知道目标IP跟端口,就可以发送UDP消息。果然UDP没有什么客户端与服务端,只是绑了一个端口而已,而且客户端也可以绑端口)
IPEndPoint sender=new IPEndPoint(IPAddress.Any,0);
clientEnd=(EndPoint)sender;
//开启一个线程连接,负责接收数据
connectThread=new Thread(new ThreadStart(SocketReceive));
connectThread.IsBackground = true;//跟随主线程退出而退出
connectThread.Start();
}
void SocketSend(string sendStr)
{
//清空发送缓存
sendData=new byte[1024];
//数据类型转换(有很多种,服务端跟客户端保持一致,解析数据才能保持正确)
sendData=Encoding.ASCII.GetBytes(sendStr);
//发送给指定客户端
socket.SendTo(sendData,sendData.Length,SocketFlags.None,clientEnd);
}
//服务器接收
void SocketReceive()
{
//进入接收循环
while(true)
{
recvData=new byte[1024];
//获取客户端,获取客户端数据,用引用给客户端赋值
recvLen=socket.ReceiveFrom(recvData,ref clientEnd);
Debug.Log(clientEnd.ToString()); //打印客户端信息(ip与端口信息,这里可以获取那些与服务器连接的客户端,毕竟是UDP检测不到断开与连接,倒是可以考虑写个心跳包功能)
//输出接收到的数据
recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
Debug.Log(recvStr);
queue.Enqueue(recvStr);//将消息存入队列
}
}
//连接关闭
void SocketQuit()
{
//关闭线程
if(connectThread!=null)
{
connectThread.Interrupt();
connectThread.Abort();
}
//最后关闭socket
if(socket!=null)
socket.Close();
}
// Update is called once per frame
void Update()
{
if(queue.Count>0)
{
//取出收到的数据进行处理再发送出去
//个人觉得还是不要在线程里面处理,毕竟如果数据庞大,还需要解析验证等环节。
sendStr="From Server: "+queue.Dequeue();
SocketSend(sendStr);
}
}
void OnApplicationQuit()
{
SocketQuit();
}
}
客户端
UDP客户端,不固定的IP,不固定的端口(可以固定),向一台已知并固定IP与端口的主机建立连接。
using UnityEngine;
using System.Collections;
//引入库
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Collections.Generic;
public class UdpClient:MonoBehaviour
{
string _string="hello wolrd";
Socket socket; //定义socket
EndPoint serverEnd; //负责服务端参数
IPEndPoint ipEnd; //用来定义目标服务端信息
//IPEndPoint ClientIpEnd; //用来定义客户端信息(固定客户端端口,可以不要,这样客户端端口就是自己随机赋值)
string recvStr; //接收的字符串
string sendStr; //发送的字符串
byte[] recvData=new byte[1024]; //接收的数据,必须为字节
byte[] sendData=new byte[1024]; //发送的数据,必须为字节
int recvLen; //接收的数据长度
Thread connectThread; //线程
Queue<string> queue = new Queue<string>();//定义一个队列(先进先出)
// Use this for initialization
void Start()
{
InitSocket(); //在这里初始化
}
void InitSocket()
{
//定义连接的服务器ip和端口,可以是本机ip,局域网,互联网(这里定义的是本机IP,毕竟是在同一台电脑上做测试)
ipEnd=new IPEndPoint(IPAddress.Parse("127.0.0.1"),5555);
//定义一个UDP连接
socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
//定义服务端(这里也没什么用。。毕竟服务端在上面已经定义好了,跟上面服务端中客户端作用一致,为了来接收收到消息是来自什么IP,什么端口)
IPEndPoint sender=new IPEndPoint(IPAddress.Any,0);
serverEnd=(EndPoint)sender;
//定义客户端端口,让客户端端口固定,否则就是随机赋值端口
//ClientIpEnd=new IPEndPoint(IPAddress.Any, 3333);
//socket.Bind(ClientIpEnd);
//建立初始连接,测试通信是否正常(必须在服务器已经运行的情况下)
SocketSend("hello");
//开启一个线程连接
connectThread=new Thread(new ThreadStart(SocketReceive));
connectThread.Start();
}
void SocketSend(string sendStr)
{
//清空发送缓存
sendData=new byte[1024];
//数据类型转换
sendData=Encoding.ASCII.GetBytes(sendStr);
//发送给指定服务端
socket.SendTo(sendData,sendData.Length,SocketFlags.None,ipEnd);
}
//接收数据
void SocketReceive()
{
//进入接收循环
while(true)
{
//对data清零
recvData=new byte[1024];
//获取服务端端数据,用引用给服务端赋值,实际上服务端已经定义好并不需要赋值(其实UPD没有什么服务端客户端的分别)
recvLen=socket.ReceiveFrom(recvData,ref serverEnd);
Debug.Log("message from: "+serverEnd.ToString()); //打印服务端信息
//输出接收到的数据
recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
Debug.Log(recvStr);
queue.Enqueue(recvStr);//将消息存入队列
}
}
//连接关闭
void SocketQuit()
{
//关闭线程
if(connectThread!=null)
{
connectThread.Interrupt();
connectThread.Abort();
}
//最后关闭socket
if(socket!=null)
socket.Close();
}
// Update is called once per frame
void Update()
{
if(queue.Count>0)
{
//取出收到的数据进行处理
//个人觉得还是不要在线程里面处理,毕竟如果数据庞大,还需要解析验证等环节。
String s=queue.Dequeue()
}
if(Input.GetKeyDown(KeyCode.Space))
{
//按下空格向服务器发送消息
SocketSend(_string);
}
}
void OnApplicationQuit()
{
SocketQuit();
}
}
除了看C#官方Socket的API,还看了下面的文章,很详细。再加上自己的理解与看法。恩,就这样。
参考:https://blog.csdn.net/u012234115/article/details/46483885?depth_1-
最后
以上就是悦耳台灯为你收集整理的Unity socket UDP 网络连接的全部内容,希望文章能够帮你解决Unity socket UDP 网络连接所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复