用阻塞的方式实现服务器多次与多个客户端收发消息
Server:
其实步骤上来说与我在Socket(一)里面的步骤都是一样的,但是仍然有几点是不同的
1.因为要处理同多个客户端收发消息 所以我用一个List来存储所有连接过来的Client
2.创建了一个Client类 来保存连接过来的Socket的信息
3.在Client里面有一个线程方法 是实时接收Client传过来的信息
在这个Client里面注意的就是ReceiveMessage()这个方法 在接收数据的时候 如果不判断连接是否断开 那么在连接断开的时候会一直接收一个空数据 然后服务端会一直打印这个空数据
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace 聊天室Server
{
class Client
{
private Socket client;
private Thread t;
private byte[] data = new byte[1024];
public Client(Socket socket)
{
client = socket;
//启动一个线程 处理客户端的 数据接收
t = new Thread(ReceiveMessage);
t.Start();
}
private void ReceiveMessage()
{
//一直接收客户端的数据
while (true)
{
//判断接收数据之前判断Socket连接是否断开 通过判断连接是否关闭
if (client.Poll(10, SelectMode.SelectRead))
{
client.Close();
break;
}
//接收客户端传过来的信息
int len = client.Receive(data);
string message = Encoding.UTF8.GetString(data, 0, len);
//把数据同步到所有客户端
Program.BroadCastMessage(message);
Console.WriteLine("收到了消息: " + message);
}
}
public void SendMessage(string message)
{
byte[] data = Encoding.UTF8.GetBytes(message);
client.Send(data);
}
public bool Connected { get { return client.Connected; } }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
//10.181.245.87
namespace 聊天室Server
{
class Program
{
static List<Client> clientList = new List<Client>();
static void Main(string[] args)
{
//创建套接字
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//创建端口号
IPAddress ip = IPAddress.Parse("10.181.245.87");
IPEndPoint point = new IPEndPoint(ip, 7788);
//绑定
serverSocket.Bind(point);
//监听
serverSocket.Listen(100);
//接收消息
while (true)
{
Socket clientSocket = serverSocket.Accept();
Console.WriteLine("一台客户端连接过来了");
Client client = new Client(clientSocket);
clientList.Add(client);
}
}
public static void BroadCastMessage(string message)
{
var notConnectedList = new List<Client>();
foreach (var client in clientList)
{
if (client.Connected)
{
client.SendMessage(message);
}
else
{
notConnectedList.Add(client);
}
}
foreach (var item in notConnectedList)
{
clientList.Remove(item);
}
}
}
}
Client端
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace 聊天室Client
{
class Program
{
private static Socket client;
static void Main(string[] args)
{
ConnectServer();
while (true)
{
byte[] data = Encoding.UTF8.GetBytes(Console.ReadLine());
client.Send(data);
}
}
static void ConnectServer()
{
//创建Socket
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//连接
IPEndPoint port=new IPEndPoint(IPAddress.Parse("10.181.245.87"),7788);
client.Connect(port);
//开启一个线程来接收消息
Thread t = new Thread(ReceiveMessage);
t.Start();
}
static void ReceiveMessage()
{
byte[] data=new byte[1024];
while (true)
{
if (client.Connected == false)
break;
int len = client.Receive(data);
Console.WriteLine(Encoding.UTF8.GetString(data, 0, len));
}
}
}
}