记录在unity 网络连接中,对 socket UDP学习过程。
2020-7-15更新 前段时间需要写广播功能、、
复制代码
1
2
3
4
5
6
7
8
9
10
11
12Socket 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。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112using 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与端口的主机建立连接。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117using 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内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复