Unity之Socket的简单使用
一、服务器Socket创建步骤
1.Socket实例化介绍
Socket serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
AddressFamily: Socket 地址簇
SocketType:指定Socket类的实例表示的套接字的类型
ProtocolType:Socket 类支持的协议
2.创建服务器ip
//服务器IP地址
//IPAddress ip = IPAddress.Parse("127.0.0.1");//127.0.0.1 为本机IP地址
IPAddress ip = IPAddress.Any; //本机地址
本地ip为什么要用IPAddress.Any而不是127.0.0.1,因为使用127.0.0.1是无法连接外网的。
具体解释:
IPAddress.Any:
3.使用IPEndPoint封装ip和端口号
private static int myProt = 59999; //端口
IPAddress ip = IPAddress.Any; //本机地址 上一步设置的ip
IPEndPoint iPEndPoint = new IPEndPoint(ip, myProt); //绑定IP地址:端口
IPEndPoint作用是用来封装ip和端口号,以便于指定一个唯一设备
4.Socket绑定ip
serverSocket.Bind(iPEndPoint); //绑定IP地址:端口
5.设置监听数量
serverSocket.Listen(10); //最多10个连接请求
6.使用线程监听连接
//服务器线程开启,写到Start中就可以了
myThread = new Thread(ListenClientConnect);
myThread.Start();
// 监听客户端是否连接
private void ListenClientConnect()
{
while (true)
{
Socket clientSocket = serverSocket.Accept(); //1.创建一个Socket 接收客户端发来的请求信息 没有消息时堵塞
clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello")); //2.向客户端发送 连接成功 消息
Thread receiveThread = new Thread(ReceiveMessage); //3.为已经连接的客户端创建一个线程 此线程用来处理客户端发送的消息
receiveThread.Start(clientSocket); //4.开启线程
//添加到字典中
string clientIp = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
//Debug.Log( clientSocket.LocalEndPoint.ToString()); //获取ip:端口号
if (!threadDic.ContainsKey(clientIp))
{
threadDic.Add(clientIp, receiveThread);
}
}
}
private byte[] result = new byte[1024]; //1.存入的byte值 最大数量1024
//开启线程接收数据 (将Socket作为值传入)
private void ReceiveMessage(object clientSocket)
{
Socket myClientSocket = (Socket)clientSocket; //2.转换传入的客户端Socket
while (true)
{
try
{
//接收数据
int receiveNumber = myClientSocket.Receive(result); //3.将客户端得到的byte值写入
//Debug.Log(receiveNumber);//子节数量
if (receiveNumber>0)
{
Debug.Log("client say :" + Encoding.ASCII.GetString(result, 0, receiveNumber));
}
else
{
Debug.Log("client: " + ((IPEndPoint)myClientSocket.RemoteEndPoint).Address.ToString() + "断开连接");
threadDic[((IPEndPoint)myClientSocket.RemoteEndPoint).Address.ToString()].Abort(); //清除线程
}
}
catch (Exception ex)
{
//myClientSocket.Shutdown(SocketShutdown.Both); //出现错误 关闭Socket
Debug.Log(" 错误信息"+ex); //打印错误信息
break;
}
}
}
最终代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class Test : MonoBehaviour
{
private static int myProt = 59999; //端口
static Socket serverSocket;
Thread myThread;
Dictionary<string, Thread> threadDic = new Dictionary<string, Thread>();//存储线程,程序结束后关闭线程
private void Start()
{
//服务器IP地址 ,127.0.0.1 为本机IP地址
IPAddress ip = IPAddress.Parse("127.0.0.1");
//IPAddress ip = IPAddress.Any; //本机地址
Debug.Log(ip.ToString());
serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPEndPoint iPEndPoint = new IPEndPoint(ip, myProt);
//serverSocket.Bind(new IPEndPoint(ip, myProt)); //绑定IP地址:端口
serverSocket.Bind(iPEndPoint); //绑定IP地址:端口
serverSocket.Listen(10); //最多10个连接请求
//Console.WriteLine("creat service {0} success",
// serverSocket.LocalEndPoint.ToString());
myThread = new Thread(ListenClientConnect);
myThread.Start();
//Console.ReadLine();
Debug.Log("服务器启动...........");
}
// 监听客户端是否连接
private void ListenClientConnect()
{
while (true)
{
Socket clientSocket = serverSocket.Accept(); //1.创建一个Socket 接收客户端发来的请求信息 没有消息时堵塞
clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello")); //2.向客户端发送 连接成功 消息
Thread receiveThread = new Thread(ReceiveMessage); //3.为已经连接的客户端创建一个线程 此线程用来处理客户端发送的消息
receiveThread.Start(clientSocket); //4.开启线程
//添加到字典中
string clientIp = ((IPEndPoint)clientSocket.RemoteEndPoint).Address.ToString();
//Debug.Log( clientSocket.LocalEndPoint.ToString()); //获取ip:端口号
if (!threadDic.ContainsKey(clientIp))
{
threadDic.Add(clientIp, receiveThread);
}
}
}
private byte[] result = new byte[1024]; //1.存入的byte值 最大数量1024
//开启线程接收数据 (将Socket作为值传入)
private void ReceiveMessage(object clientSocket)
{
Socket myClientSocket = (Socket)clientSocket; //2.转换传入的客户端Socket
while (true)
{
try
{
//接收数据
int receiveNumber = myClientSocket.Receive(result); //3.将客户端得到的byte值写入
//Debug.Log(receiveNumber);//子节数量
if (receiveNumber>0)
{
Debug.Log("client say :" + Encoding.ASCII.GetString(result, 0, receiveNumber));
}
else
{
Debug.Log("client: " + ((IPEndPoint)myClientSocket.RemoteEndPoint).Address.ToString() + "断开连接");
threadDic[((IPEndPoint)myClientSocket.RemoteEndPoint).Address.ToString()].Abort(); //清除线程
}
}
catch (Exception ex)
{
//myClientSocket.Shutdown(SocketShutdown.Both); //出现错误 关闭Socket
Debug.Log(" 错误信息"+ex); //打印错误信息
break;
}
}
}
void OnApplicationQuit()
{
//结束线程必须关闭 否则下次开启会出现错误 (如果出现的话 只能重启unity了)
myThread.Abort();
//关闭开启的线程
foreach (string item in threadDic.Keys)
{
Debug.Log(item);//de.Key对应于key/value键值对key
//item.Value.GetType()
threadDic[item].Abort();
}
}
}
二、创建客户端
步骤和上面差不多,只不过客户端是将绑定Bind()换成Connect()连接服务器即可
代码:
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using UnityEngine.UI;
using UnityEngine;
using System;
public class ClientTest : MonoBehaviour
{
public Button sendBtn;//发送
public InputField inputfield;//信息
Socket clientSocket;
private static byte[] result = new byte[1024];
void Start()
{
sendBtn.onClick.AddListener(SetMessage);
//要连接的服务器IP地址
IPAddress ip = IPAddress.Parse("10.25.4.133");//本地IP地址
//IPAddress ip = IPAddress.Any;//本地IP地址
clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
try
{
clientSocket.Connect(new IPEndPoint(ip, 59999)); //配置服务器IP与端口 ,并且尝试连接
Debug.Log("Connect Success"); //没有出错 打印连接成功
}
catch (Exception ex)
{
Debug.Log("Connect lose"+ ex); //打印连接失败
return;
}
int receiveLength = clientSocket.Receive(result);//接收服务器回复消息,成功则说明已经接通
Debug.Log("开始"+ receiveLength);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
//开始发送数据
try
{
if (isShow)
{
isShow = false;//发送后 变为false 直到按钮再次点击发送
string sendMessage = inputfield.text;
Debug.Log("发送信息" + sendMessage);
clientSocket.Send(Encoding.ASCII.GetBytes(sendMessage));//传送信息
}
}
catch (Exception ex)
{
Debug.Log("发送失败:"+ ex);
//clientSocket.Shutdown(SocketShutdown.Both); //出现问题关闭socket
}
}
//单击按钮发送信息
bool isShow = false; //用来判断是否发送信息的
void SetMessage()
{
//输入框不为空 发送消息
if (!inputfield.text.Equals(string.Empty))
isShow = true;
}
}