求助 套接字问题 我是学.net的新手,现在遇到了点问题 ,就是套接字的 多个客户端怎样给服务端发送信息 ,服务端是循环接收客户端的连接请求的,现在多个客户端连上后 只能一个客户端给服务端发送。高人请帮助 ,谢谢.net 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 服务器socket listen后,accept会生成1个新的连接,每次你都把这个连接给新的对象,就有多个连接,就可以同时接收多个客户端的发送了。 服务器端的一个代码例子,包括接收客户端以及接收数据 /// <summary> /// 收包处理委托 /// </summary> /// <param name="buffer"></param> /// <param name="socket"></param> /// <returns></returns> public delegate bool ReceivePacketHandle(byte[] buffer, Socket socket); /// <summary> /// 客户端接受委托 /// </summary> public delegate void ClientChangedHandle(object state); public abstract class PacketTransferBase { /// <summary> /// Socket列表 /// </summary> public SortedList<int, Socket> SocketClientList { get; private set; } /// <summary> /// 客户端接收事件 /// </summary> public event ClientChangedHandle OnClientAccepted; /// <summary> /// 客户端关闭事件 /// </summary> public event ClientChangedHandle OnClientClosed; /// <summary> /// 收包处理事件 /// </summary> public event ReceivePacketHandle OnReceivePacket; public PacketTransferBase() { SocketClientList = new SortedList<int, Socket>(); } /// <summary> /// 保存客户端,以待每次接收后进行判断等功能 /// </summary> /// <param name="socketClient"></param> protected void AddClient(Socket socketClient) { lock (SocketClientList) { HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("Add Socket:{0}.{1}", socketClient.Handle, socketClient.Connected)); SocketClientList.Add(socketClient.Handle.ToInt32(), socketClient); } //bufferList.Add(clientCount, new byte[1024]); if (OnClientAccepted != null) { OnClientAccepted(socketClient.Handle.ToInt32()); } } /// <summary> /// 接收信息 /// </summary> /// <param name="ar"></param> protected void ReceiveMessage(IAsyncResult ar) { try { StateObject so = (StateObject)ar.AsyncState; Socket socket = so.workSocket; //var socket = ar.AsyncState as Socket; //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx var length = socket.EndReceive(ar); byte[] actualData = new byte[length]; Array.Copy(so.buffer, 0, actualData, 0, length); //fileManager.ReceivePacket(actualData); HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("TCPServer.ReceiveMessage: buffer.{0} at Socket.{1} with buffer[23].{2},buffer[24].{3}", length, socket.Handle, so.buffer[23], so.buffer[24])); //fileManager.ReceivePacket(actualData, socket); //FileTransferManagerServer server = FileTransferManagerServer.GetInstance(); //server.ReceivePacket(actualData, socket); bool continueReceive = false; if (OnReceivePacket != null) { continueReceive = OnReceivePacket(actualData, socket); } //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了) //socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket); if (continueReceive) { socket.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveMessage), so); } else { Clean(socket); //socket.Close(); } } catch (Exception ex) { HYTLogging.NCLogger.GetInstance().WriteInfoLog(ex.Message + ex.StackTrace); } } /// <summary> /// 从列表中移除Socket,并关闭Socket /// </summary> /// <param name="socket"></param> protected void Clean(Socket socket) { HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("Clean Socket:{0}.{1}", socket.Handle, socket.Connected)); int socketHandle = socket.Handle.ToInt32(); lock (SocketClientList) { if (SocketClientList.ContainsKey(socketHandle)) { SocketClientList.Remove(socketHandle); } } socket.Close(); if (OnClientClosed != null) { OnClientClosed(socketHandle); } } } /// <summary> /// TCP服务器端 /// </summary> public class TCPServer : PacketTransferBase { public string ServerIP { get; set; } public int ServerPort { get; set; } //public Socket[] SocketClientList { get; private set; } private static TCPServer tcpServer = new TCPServer(); Socket socketServer = null; //FileManager fileManager = new FileManager(FileControl.FileReceive, TCPModel.TCPServer); //FileManager fileManager = new FileManager(FileControl.FileSend, TransferModel.TCPServer); private TCPServer() { //SocketClientList = new Socket[10]; //SocketClientList = new SortedList<int, Socket>(); } public static PacketTransferBase GetInstance() { return tcpServer; } /// <summary> /// 服务器端建立侦听 /// </summary> public void CreatListener() { //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字) socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //将该socket绑定到主机上面的某个端口 //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx //socketServer.Bind(new IPEndPoint(IPAddress.Any, 4530)); socketServer.Bind(new IPEndPoint(IPAddress.Parse(ServerIP), ServerPort)); //启动监听,并且设置一个最大的队列长度 //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx socketServer.Listen(100); //开始接受客户端连接请求 //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx socketServer.BeginAccept(new AsyncCallback(ClientAccepted), socketServer); } /// <summary> /// 接收客户端 /// </summary> /// <param name="ar"></param> public void ClientAccepted(IAsyncResult ar) { try { var socketServer = ar.AsyncState as Socket; //这就是客户端的Socket实例,我们后续可以将其保存起来 var socketClient = socketServer.EndAccept(ar); AddClient(socketClient); //接收客户端的消息(这个和在客户端实现的方式是一样的) StateObject so = new StateObject(); so.workSocket = socketClient; socketClient.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveMessage), so); //准备接受下一个客户端请求 socketServer.BeginAccept(new AsyncCallback(ClientAccepted), socketServer); } catch (Exception ex) { HYTLogging.NCLogger.GetInstance().WriteInfoLog(ex.Message + ex.StackTrace); } } } public class StateObject { public Socket workSocket = null; public EndPoint tempRemoteEP = null; public const int BUFFER_SIZE = 1024; public byte[] buffer = new byte[BUFFER_SIZE]; } 你把 HYTLogging.NCLogger.GetInstance().....都注释就行,这是我记日志用的 当客户端连接上服务器以后 你发送的时候还要用连接的那个tcpclient去发送消息而不是重新实例化一个新的tcpclient 你所说的嵌套报错应该是在没有断开的情况下又重新连接了 端口号还用的是同一个 richTextBox控件是不是有BUG啊? MutilGridHeader是什么意思?怎么用? 如何用C#获得内嵌的二进制资源? listbox控件的选取值如何传递给参数? 问C#函数调用别函数的变量的解决方法 这段代码如何简化 急!急!急!更新Excel数据源!!问题! 如何动态的执行c#语句 C#.Net窗体中如何接收键盘事件及如何处理它? 。NET 所谓接口就是了一个接口对象实现了操作多个不同类的方法么 问个c#中常用的集合类型?
/// 收包处理委托
/// </summary>
/// <param name="buffer"></param>
/// <param name="socket"></param>
/// <returns></returns>
public delegate bool ReceivePacketHandle(byte[] buffer, Socket socket); /// <summary>
/// 客户端接受委托
/// </summary>
public delegate void ClientChangedHandle(object state); public abstract class PacketTransferBase
{
/// <summary>
/// Socket列表
/// </summary>
public SortedList<int, Socket> SocketClientList { get; private set; } /// <summary>
/// 客户端接收事件
/// </summary>
public event ClientChangedHandle OnClientAccepted; /// <summary>
/// 客户端关闭事件
/// </summary>
public event ClientChangedHandle OnClientClosed; /// <summary>
/// 收包处理事件
/// </summary>
public event ReceivePacketHandle OnReceivePacket; public PacketTransferBase()
{
SocketClientList = new SortedList<int, Socket>();
} /// <summary>
/// 保存客户端,以待每次接收后进行判断等功能
/// </summary>
/// <param name="socketClient"></param>
protected void AddClient(Socket socketClient)
{
lock (SocketClientList)
{
HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("Add Socket:{0}.{1}", socketClient.Handle, socketClient.Connected));
SocketClientList.Add(socketClient.Handle.ToInt32(), socketClient);
}
//bufferList.Add(clientCount, new byte[1024]);
if (OnClientAccepted != null)
{
OnClientAccepted(socketClient.Handle.ToInt32());
}
} /// <summary>
/// 接收信息
/// </summary>
/// <param name="ar"></param>
protected void ReceiveMessage(IAsyncResult ar)
{
try
{
StateObject so = (StateObject)ar.AsyncState;
Socket socket = so.workSocket;
//var socket = ar.AsyncState as Socket; //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
var length = socket.EndReceive(ar);
byte[] actualData = new byte[length];
Array.Copy(so.buffer, 0, actualData, 0, length);
//fileManager.ReceivePacket(actualData);
HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("TCPServer.ReceiveMessage: buffer.{0} at Socket.{1} with buffer[23].{2},buffer[24].{3}", length, socket.Handle, so.buffer[23], so.buffer[24]));
//fileManager.ReceivePacket(actualData, socket);
//FileTransferManagerServer server = FileTransferManagerServer.GetInstance();
//server.ReceivePacket(actualData, socket);
bool continueReceive = false;
if (OnReceivePacket != null)
{
continueReceive = OnReceivePacket(actualData, socket);
} //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
//socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
if (continueReceive)
{
socket.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveMessage), so);
}
else
{
Clean(socket);
//socket.Close();
}
}
catch (Exception ex)
{
HYTLogging.NCLogger.GetInstance().WriteInfoLog(ex.Message + ex.StackTrace);
}
} /// <summary>
/// 从列表中移除Socket,并关闭Socket
/// </summary>
/// <param name="socket"></param>
protected void Clean(Socket socket)
{
HYTLogging.NCLogger.GetInstance().WriteInfoLog(string.Format("Clean Socket:{0}.{1}", socket.Handle, socket.Connected));
int socketHandle = socket.Handle.ToInt32();
lock (SocketClientList)
{
if (SocketClientList.ContainsKey(socketHandle))
{
SocketClientList.Remove(socketHandle);
}
}
socket.Close();
if (OnClientClosed != null)
{
OnClientClosed(socketHandle);
}
}
} /// <summary>
/// TCP服务器端
/// </summary>
public class TCPServer : PacketTransferBase
{
public string ServerIP { get; set; }
public int ServerPort { get; set; }
//public Socket[] SocketClientList { get; private set; }
private static TCPServer tcpServer = new TCPServer();
Socket socketServer = null;
//FileManager fileManager = new FileManager(FileControl.FileReceive, TCPModel.TCPServer);
//FileManager fileManager = new FileManager(FileControl.FileSend, TransferModel.TCPServer); private TCPServer()
{
//SocketClientList = new Socket[10];
//SocketClientList = new SortedList<int, Socket>();
} public static PacketTransferBase GetInstance()
{
return tcpServer;
} /// <summary>
/// 服务器端建立侦听
/// </summary>
public void CreatListener()
{
//创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //将该socket绑定到主机上面的某个端口
//方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
//socketServer.Bind(new IPEndPoint(IPAddress.Any, 4530));
socketServer.Bind(new IPEndPoint(IPAddress.Parse(ServerIP), ServerPort)); //启动监听,并且设置一个最大的队列长度
//方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
socketServer.Listen(100); //开始接受客户端连接请求
//方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx
socketServer.BeginAccept(new AsyncCallback(ClientAccepted), socketServer);
}
/// <summary>
/// 接收客户端
/// </summary>
/// <param name="ar"></param>
public void ClientAccepted(IAsyncResult ar)
{
try
{
var socketServer = ar.AsyncState as Socket; //这就是客户端的Socket实例,我们后续可以将其保存起来
var socketClient = socketServer.EndAccept(ar);
AddClient(socketClient); //接收客户端的消息(这个和在客户端实现的方式是一样的)
StateObject so = new StateObject();
so.workSocket = socketClient;
socketClient.BeginReceive(so.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveMessage), so); //准备接受下一个客户端请求
socketServer.BeginAccept(new AsyncCallback(ClientAccepted), socketServer);
}
catch (Exception ex)
{
HYTLogging.NCLogger.GetInstance().WriteInfoLog(ex.Message + ex.StackTrace);
}
}
} public class StateObject
{
public Socket workSocket = null;
public EndPoint tempRemoteEP = null;
public const int BUFFER_SIZE = 1024;
public byte[] buffer = new byte[BUFFER_SIZE];
}
而不是重新实例化一个新的tcpclient 你所说的嵌套报错应该是在没有断开的情况下又重新连接了
端口号还用的是同一个