建立两个unity工程,编写脚本。
服务端
[csharp]
1. using UnityEngine;
2. using System.Collections;
3. //引入库
4. using System.Net;
5. using System.Net.Sockets;
6. using System.Text;
7. using System.Threading;
8.
9. public class TcpServer:MonoBehaviour
10. {
11. //以下默认都是私有的成员
12. //服务器端socket
13. //客户端socket
14. //侦听端口
15. string recvStr; //接收的字符串
16. string sendStr; //发送的字符串
17. byte[] recvData=new byte[1024]; //接收的数据,必须为字节
18. byte[] sendData=new byte[1024]; //发送的数据,必须为字节
19. int recvLen; //接收的数据长度
20. //连接线程
21.
22. //初始化
23. void InitSocket()
24. {
25. //定义侦听端口,侦听任何IP
26. new IPEndPoint(IPAddress.Any,5566);
27. //定义套接字类型,在主线程中定义
28. new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
29. //连接
30. serverSocket.Bind(ipEnd);
31. //开始侦听,最大10个连接
32. serverSocket.Listen(10);
33.
34.
35.
36. //开启一个线程连接,必须的,否则主线程卡死
37. new Thread(new ThreadStart(SocketReceive));
38. connectThread.Start();
39. }
40.
41. //连接
42. void SocketConnet()
43. {
44. if(clientSocket!=null)
45. clientSocket.Close();
46. //控制台输出侦听状态
47. "Waiting for a client");
48. //一旦接受连接,创建一个客户端
49. clientSocket=serverSocket.Accept();
50. //获取客户端的IP和端口
51. IPEndPoint ipEndClient=(IPEndPoint)clientSocket.RemoteEndPoint;
52. //输出客户端的IP和端口
53. "Connect with "+ipEndClient.Address.ToString()+":"+ipEndClient.Port.ToString());
54. //连接成功则发送数据
55. "Welcome to my server";
56. SocketSend(sendStr);
57. }
58.
59. void SocketSend(string sendStr)
60. {
61. //清空发送缓存
62. new byte[1024];
63. //数据类型转换
64. sendData=Encoding.ASCII.GetBytes(sendStr);
65. //发送
66. clientSocket.Send(sendData,sendData.Length,SocketFlags.None);
67. }
68.
69. //服务器接收
70. void SocketReceive()
71. {
72. //连接
73. SocketConnet();
74. //进入接收循环
75. while(true)
76. {
77. //对data清零
78. new byte[1024];
79. //获取收到的数据的长度
80. recvLen=clientSocket.Receive(recvData);
81. //如果收到的数据长度为0,则重连并进入下一个循环
82. if(recvLen==0)
83. {
84. SocketConnet();
85. continue;
86. }
87. //输出接收到的数据
88. recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
89. print(recvStr);
90. //将接收到的数据经过处理再发送出去
91. "From Server: "+recvStr;
92. SocketSend(sendStr);
93. }
94. }
95.
96. //连接关闭
97. void SocketQuit()
98. {
99. //先关闭客户端
100. if(clientSocket!=null)
101. clientSocket.Close();
102. //再关闭线程
103. if(connectThread!=null)
104. {
105. connectThread.Interrupt();
106. connectThread.Abort();
107. }
108. //最后关闭服务器
109. serverSocket.Close();
110. "diconnect");
111. }
112.
113. // Use this for initialization
114. void Start()
115. {
116. //在这里初始化server
117. }
118.
119.
120. // Update is called once per frame
121. void Update()
122. {
123.
124. }
125.
126. void OnApplicationQuit()
127. {
128. SocketQuit();
129. }
130. }
- 创建套接字
- 绑定套接字到ip和端口
- 侦听连接
- 接收连接
- 与客户端收发数据
- 返回等待另一连接
- 断开连接
把脚本挂到unity场景中某个物体上,比如camera,由于创建连接后有接收循环,所以要单独开一个线程,否则主线程会卡死。
客户端
[csharp]
1. using UnityEngine;
2. using System.Collections;
3. //引入库
4. using System.Net;
5. using System.Net.Sockets;
6. using System.Text;
7. using System.Threading;
8.
9. public class TcpClient:MonoBehaviour
10. {
11. string editString="hello wolrd"; //编辑框文字
12.
13. //服务器端socket
14. //主机ip
15. IPEndPoint ipEnd;
16. string recvStr; //接收的字符串
17. string sendStr; //发送的字符串
18. byte[] recvData=new byte[1024]; //接收的数据,必须为字节
19. byte[] sendData=new byte[1024]; //发送的数据,必须为字节
20. int recvLen; //接收的数据长度
21. //连接线程
22.
23. //初始化
24. void InitSocket()
25. {
26. //定义服务器的IP和端口,端口与服务器对应
27. "127.0.0.1"); //可以是局域网或互联网ip,此处是本机
28. new IPEndPoint(ip,5566);
29.
30.
31. //开启一个线程连接,必须的,否则主线程卡死
32. new Thread(new ThreadStart(SocketReceive));
33. connectThread.Start();
34. }
35.
36. void SocketConnet()
37. {
38. if(serverSocket!=null)
39. serverSocket.Close();
40. //定义套接字类型,必须在子线程中定义
41. new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
42. "ready to connect");
43. //连接
44. serverSocket.Connect(ipEnd);
45.
46. //输出初次连接收到的字符串
47. recvLen=serverSocket.Receive(recvData);
48. recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
49. print(recvStr);
50. }
51.
52. void SocketSend(string sendStr)
53. {
54. //清空发送缓存
55. new byte[1024];
56. //数据类型转换
57. sendData=Encoding.ASCII.GetBytes(sendStr);
58. //发送
59. serverSocket.Send(sendData,sendData.Length,SocketFlags.None);
60. }
61.
62. void SocketReceive()
63. {
64. SocketConnet();
65. //不断接收服务器发来的数据
66. while(true)
67. {
68. new byte[1024];
69. recvLen=serverSocket.Receive(recvData);
70. if(recvLen==0)
71. {
72. SocketConnet();
73. continue;
74. }
75. recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
76. print(recvStr);
77. }
78. }
79.
80. void SocketQuit()
81. {
82. //关闭线程
83. if(connectThread!=null)
84. {
85. connectThread.Interrupt();
86. connectThread.Abort();
87. }
88. //最后关闭服务器
89. if(serverSocket!=null)
90. serverSocket.Close();
91. "diconnect");
92. }
93.
94. // Use this for initialization
95. void Start()
96. {
97. InitSocket();
98. }
99.
100. void OnGUI()
101. {
102. new Rect(10,10,100,20),editString);
103. if(GUI.Button(new Rect(10,30,60,20),"send"))
104. SocketSend(editString);
105. }
106.
107. // Update is called once per frame
108. void Update()
109. {
110.
111. }
112.
113. //程序退出则关闭连接
114. void OnApplicationQuit()
115. {
116. SocketQuit();
117. }
118. }
- 创建套接字
- 向服务器发出连接请求
- 和服务器通信
- 断开连接
同样把脚本挂到场景某个物体中,创建连接和接收循环都放在新开的线程里面,在界面上放一个文字编辑框和一个button用于给服务端发消息。
测试
程序实现的功能为,当一个新的客户端连接到服务端时,服务端控制台输出相关信息,并向客户端发送初始信息,客户端每次向服务端的信息由服务端接收后添加一段字符串再发送回来。
建立两个unity工程,编写脚本。
服务端
[csharp]
1. using UnityEngine;
2. using System.Collections;
3. //引入库
4. using System.Net;
5. using System.Net.Sockets;
6. using System.Text;
7. using System.Threading;
8.
9. public class TcpServer:MonoBehaviour
10. {
11. //以下默认都是私有的成员
12. //服务器端socket
13. //客户端socket
14. //侦听端口
15. string recvStr; //接收的字符串
16. string sendStr; //发送的字符串
17. byte[] recvData=new byte[1024]; //接收的数据,必须为字节
18. byte[] sendData=new byte[1024]; //发送的数据,必须为字节
19. int recvLen; //接收的数据长度
20. //连接线程
21.
22. //初始化
23. void InitSocket()
24. {
25. //定义侦听端口,侦听任何IP
26. new IPEndPoint(IPAddress.Any,5566);
27. //定义套接字类型,在主线程中定义
28. new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
29. //连接
30. serverSocket.Bind(ipEnd);
31. //开始侦听,最大10个连接
32. serverSocket.Listen(10);
33.
34.
35.
36. //开启一个线程连接,必须的,否则主线程卡死
37. new Thread(new ThreadStart(SocketReceive));
38. connectThread.Start();
39. }
40.
41. //连接
42. void SocketConnet()
43. {
44. if(clientSocket!=null)
45. clientSocket.Close();
46. //控制台输出侦听状态
47. "Waiting for a client");
48. //一旦接受连接,创建一个客户端
49. clientSocket=serverSocket.Accept();
50. //获取客户端的IP和端口
51. IPEndPoint ipEndClient=(IPEndPoint)clientSocket.RemoteEndPoint;
52. //输出客户端的IP和端口
53. "Connect with "+ipEndClient.Address.ToString()+":"+ipEndClient.Port.ToString());
54. //连接成功则发送数据
55. "Welcome to my server";
56. SocketSend(sendStr);
57. }
58.
59. void SocketSend(string sendStr)
60. {
61. //清空发送缓存
62. new byte[1024];
63. //数据类型转换
64. sendData=Encoding.ASCII.GetBytes(sendStr);
65. //发送
66. clientSocket.Send(sendData,sendData.Length,SocketFlags.None);
67. }
68.
69. //服务器接收
70. void SocketReceive()
71. {
72. //连接
73. SocketConnet();
74. //进入接收循环
75. while(true)
76. {
77. //对data清零
78. new byte[1024];
79. //获取收到的数据的长度
80. recvLen=clientSocket.Receive(recvData);
81. //如果收到的数据长度为0,则重连并进入下一个循环
82. if(recvLen==0)
83. {
84. SocketConnet();
85. continue;
86. }
87. //输出接收到的数据
88. recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
89. print(recvStr);
90. //将接收到的数据经过处理再发送出去
91. "From Server: "+recvStr;
92. SocketSend(sendStr);
93. }
94. }
95.
96. //连接关闭
97. void SocketQuit()
98. {
99. //先关闭客户端
100. if(clientSocket!=null)
101. clientSocket.Close();
102. //再关闭线程
103. if(connectThread!=null)
104. {
105. connectThread.Interrupt();
106. connectThread.Abort();
107. }
108. //最后关闭服务器
109. serverSocket.Close();
110. "diconnect");
111. }
112.
113. // Use this for initialization
114. void Start()
115. {
116. //在这里初始化server
117. }
118.
119.
120. // Update is called once per frame
121. void Update()
122. {
123.
124. }
125.
126. void OnApplicationQuit()
127. {
128. SocketQuit();
129. }
130. }
- 创建套接字
- 绑定套接字到ip和端口
- 侦听连接
- 接收连接
- 与客户端收发数据
- 返回等待另一连接
- 断开连接
把脚本挂到unity场景中某个物体上,比如camera,由于创建连接后有接收循环,所以要单独开一个线程,否则主线程会卡死。
客户端
[csharp]
1. using UnityEngine;
2. using System.Collections;
3. //引入库
4. using System.Net;
5. using System.Net.Sockets;
6. using System.Text;
7. using System.Threading;
8.
9. public class TcpClient:MonoBehaviour
10. {
11. string editString="hello wolrd"; //编辑框文字
12.
13. //服务器端socket
14. //主机ip
15. IPEndPoint ipEnd;
16. string recvStr; //接收的字符串
17. string sendStr; //发送的字符串
18. byte[] recvData=new byte[1024]; //接收的数据,必须为字节
19. byte[] sendData=new byte[1024]; //发送的数据,必须为字节
20. int recvLen; //接收的数据长度
21. //连接线程
22.
23. //初始化
24. void InitSocket()
25. {
26. //定义服务器的IP和端口,端口与服务器对应
27. "127.0.0.1"); //可以是局域网或互联网ip,此处是本机
28. new IPEndPoint(ip,5566);
29.
30.
31. //开启一个线程连接,必须的,否则主线程卡死
32. new Thread(new ThreadStart(SocketReceive));
33. connectThread.Start();
34. }
35.
36. void SocketConnet()
37. {
38. if(serverSocket!=null)
39. serverSocket.Close();
40. //定义套接字类型,必须在子线程中定义
41. new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
42. "ready to connect");
43. //连接
44. serverSocket.Connect(ipEnd);
45.
46. //输出初次连接收到的字符串
47. recvLen=serverSocket.Receive(recvData);
48. recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
49. print(recvStr);
50. }
51.
52. void SocketSend(string sendStr)
53. {
54. //清空发送缓存
55. new byte[1024];
56. //数据类型转换
57. sendData=Encoding.ASCII.GetBytes(sendStr);
58. //发送
59. serverSocket.Send(sendData,sendData.Length,SocketFlags.None);
60. }
61.
62. void SocketReceive()
63. {
64. SocketConnet();
65. //不断接收服务器发来的数据
66. while(true)
67. {
68. new byte[1024];
69. recvLen=serverSocket.Receive(recvData);
70. if(recvLen==0)
71. {
72. SocketConnet();
73. continue;
74. }
75. recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);
76. print(recvStr);
77. }
78. }
79.
80. void SocketQuit()
81. {
82. //关闭线程
83. if(connectThread!=null)
84. {
85. connectThread.Interrupt();
86. connectThread.Abort();
87. }
88. //最后关闭服务器
89. if(serverSocket!=null)
90. serverSocket.Close();
91. "diconnect");
92. }
93.
94. // Use this for initialization
95. void Start()
96. {
97. InitSocket();
98. }
99.
100. void OnGUI()
101. {
102. new Rect(10,10,100,20),editString);
103. if(GUI.Button(new Rect(10,30,60,20),"send"))
104. SocketSend(editString);
105. }
106.
107. // Update is called once per frame
108. void Update()
109. {
110.
111. }
112.
113. //程序退出则关闭连接
114. void OnApplicationQuit()
115. {
116. SocketQuit();
117. }
118. }
- 创建套接字
- 向服务器发出连接请求
- 和服务器通信
- 断开连接
同样把脚本挂到场景某个物体中,创建连接和接收循环都放在新开的线程里面,在界面上放一个文字编辑框和一个button用于给服务端发消息。
测试
程序实现的功能为,当一个新的客户端连接到服务端时,服务端控制台输出相关信息,并向客户端发送初始信息,客户端每次向服务端的信息由服务端接收后添加一段字符串再发送回来。