using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace TeachTcpServerExercises2
{
class ServerSocket
{
//服务端Socket
public Socket socket;
//客户端连接的所有Socket
public Dictionary<int, ClientSocket> clientDic = new Dictionary<int, ClientSocket>();
private bool isClose;
//开启服务器端
public void Start(string ip, int port, int num)
{
isClose = false;
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ip), port);
socket.Bind(ipPoint);
socket.Listen(num);
ThreadPool.QueueUserWorkItem(Accept);
ThreadPool.QueueUserWorkItem(Receive);
}
//关闭服务器端
public void Close()
{
isClose = true;
foreach (ClientSocket client in clientDic.Values)
{
client.Close();
}
clientDic.Clear();
socket.Shutdown(SocketShutdown.Both);
socket.Close();
socket = null;
}
//接受客户端连入
private void Accept(object obj)
{
while (!isClose)
{
try
{
//连入一个客户端
Socket clientSocket = socket.Accept();
ClientSocket client = new ClientSocket(clientSocket);
client.Send("欢迎连入服务器");
clientDic.Add(client.clientID, client);
}
catch (Exception e)
{
Console.WriteLine("客户端连入报错" + e.Message);
}
}
}
//接收客户端消息
private void Receive(object obj)
{
while (!isClose)
{
if(clientDic.Count > 0)
{
foreach (ClientSocket client in clientDic.Values)
{
client.Receive();
}
}
}
}
public void Broadcast(string info)
{
foreach (ClientSocket client in clientDic.Values)
{
client.Send(info);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace TeachTcpServerExercises2
{
class ClientSocket
{
private static int CLIENT_BEGIN_ID = 1;
public int clientID;
public Socket socket;
public ClientSocket(Socket socket)
{
this.clientID = CLIENT_BEGIN_ID;
this.socket = socket;
++CLIENT_BEGIN_ID;
}
/// <summary>
/// 是否是连接状态
/// </summary>
public bool Connected => this.socket.Connected;
//我们应该封装一些方法
//关闭
public void Close()
{
if(socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
socket = null;
}
}
//发送
public void Send(string info)
{
if(socket != null)
{
try
{
socket.Send(Encoding.UTF8.GetBytes(info));
}
catch(Exception e)
{
Console.WriteLine("发消息出错" + e.Message);
Close();
}
}
}
//接收
public void Receive()
{
if (socket == null)
return;
try
{
if(socket.Available > 0)
{
byte[] result = new byte[1024 * 5];
int receiveNum = socket.Receive(result);
ThreadPool.QueueUserWorkItem(MsgHandle, Encoding.UTF8.GetString(result, 0, receiveNum));
}
}
catch (Exception e)
{
Console.WriteLine("收消息出错" + e.Message);
Close();
}
}
private void MsgHandle(object obj)
{
string str = obj as string;
Console.WriteLine("收到客户端{0}发来的消息:{1}", this.socket.RemoteEndPoint, str);
}
}
}
using System;
namespace TeachTcpServerExercises2
{
class Program
{
static void Main(string[] args)
{
ServerSocket socket = new ServerSocket();
socket.Start("127.0.0.1", 8080, 1024);
Console.WriteLine("服务器开启成功");
while (true)
{
string input = Console.ReadLine();
if(input == "Quit")
{
socket.Close();
}
else if( input.Substring(0,2) == "B:" )
{
socket.Broadcast(input.Substring(2));
}
}
}
}
}
客户端
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class NetMgr : MonoBehaviour
{
private static NetMgr instance;
public static NetMgr Instance => instance;
//客户端Socket
private Socket socket;
//用于发送消息的队列 公共容器 主线程往里面放 发送线程从里面取
private Queue<string> sendMsgQueue = new Queue<string>();
//用于接收消息的对象 公共容器 子线程往里面放 主线程从里面取
private Queue<string> receiveQueue = new Queue<string>();
//用于收消息的水桶(容器)
private byte[] receiveBytes = new byte[1024 * 1024];
//返回收到的字节数
private int receiveNum;
//是否连接
private bool isConnected = false;
void Awake()
{
instance = this;
DontDestroyOnLoad(this.gameObject);
}
// Update is called once per frame
void Update()
{
if(receiveQueue.Count > 0)
{
print(receiveQueue.Dequeue());
}
}
//连接服务端
public void Connect(string ip, int port)
{
//如果是连接状态 直接返回
if (isConnected)
return;
if (socket == null)
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//连接服务端
IPEndPoint ipPoint = new IPEndPoint(IPAddress.Parse(ip), port);
try
{
socket.Connect(ipPoint);
isConnected = true;
//开启发送线程
ThreadPool.QueueUserWorkItem(SendMsg);
//开启接收线程
ThreadPool.QueueUserWorkItem(ReceiveMsg);
}
catch (SocketException e)
{
if (e.ErrorCode == 10061)
print("服务器拒绝连接");
else
print("连接失败" + e.ErrorCode + e.Message);
}
}
//发送消息
public void Send(string info)
{
sendMsgQueue.Enqueue(info);
}
private void SendMsg(object obj)
{
while (isConnected)
{
if (sendMsgQueue.Count > 0)
{
socket.Send(Encoding.UTF8.GetBytes(sendMsgQueue.Dequeue()));
}
}
}
//不停的接受消息
private void ReceiveMsg(object obj)
{
while (isConnected)
{
if(socket.Available > 0)
{
receiveNum = socket.Receive(receiveBytes);
//收到消息 解析消息为字符串 并放入公共容器
receiveQueue.Enqueue(Encoding.UTF8.GetString(receiveBytes, 0, receiveNum));
}
}
}
public void Close()
{
if(socket != null)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
isConnected = false;
}
}
private void OnDestroy()
{
Close();
}
}