C#,异步套接字服务器/客户端,StackOverflowException
我正在用C#编写一个异步服务器和客户端。我从MSDN中提取了示例代码,对其进行了多次修改,使其能够发送和接收消息。我尝试将5个或更多的客户端连接到服务器,但在第98次迭代中,每个客户端都会抛出异常堆栈溢出。有人能解释我为什么会犯这个错误吗?我在MSDN中读到,我的问题存在于无限循环中,但我不明白如何在没有循环的情况下修改代码并编写代码 这个服务器客户端应该在多人赛车游戏中使用,我需要每秒发送和接收每个玩家的坐标数次。如果没有无限循环,我怎么做呢 这是我的密码: 服务器:C#,异步套接字服务器/客户端,StackOverflowException,c#,sockets,asynchronous,stack-overflow,C#,Sockets,Asynchronous,Stack Overflow,我正在用C#编写一个异步服务器和客户端。我从MSDN中提取了示例代码,对其进行了多次修改,使其能够发送和接收消息。我尝试将5个或更多的客户端连接到服务器,但在第98次迭代中,每个客户端都会抛出异常堆栈溢出。有人能解释我为什么会犯这个错误吗?我在MSDN中读到,我的问题存在于无限循环中,但我不明白如何在没有循环的情况下修改代码并编写代码 这个服务器客户端应该在多人赛车游戏中使用,我需要每秒发送和接收每个玩家的坐标数次。如果没有无限循环,我怎么做呢 这是我的密码: 服务器: using System
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class Server
{
Socket main_tcp_Sock;
private static ManualResetEvent acceptDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent recvDone = new ManualResetEvent(false);
private static ManualResetEvent closeDone = new ManualResetEvent(false);
//int cl_Count = 0;
List<StateObject> connection_List = new List<StateObject>();
private static String response = String.Empty;
public class StateObject
{
public Socket current_Socket = null;
public byte[] data = new byte[256];
public string id = string.Empty;
}
public Server()
{
Server_Start();
}
public void Server_Start()
{
//Creating socket
main_tcp_Sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2000);
//Bind socket
try
{
main_tcp_Sock.Bind(ipLocal);
Console.WriteLine("Server has started successfully!");
//Start listening
main_tcp_Sock.Listen(100);
while (true)
{
acceptDone.Reset();
Console.WriteLine("Waiting for a connection...");
//AsyncAccept
main_tcp_Sock.BeginAccept(new AsyncCallback(On_Connect), main_tcp_Sock);
acceptDone.WaitOne();
Console.WriteLine("\nPress any button to continue...\n\n");
Console.ReadKey(true);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
public void On_Connect(IAsyncResult asyn)
{
try
{
Socket listener = (Socket)asyn.AsyncState;
Socket handler = listener.EndAccept(asyn);
acceptDone.Set();
StateObject connection = new StateObject();
connection.current_Socket = handler;
if (!connection_List.Contains(connection))
{
lock (connection_List)
{
connection_List.Add(connection);
connection.id = "00" + connection_List.Count.ToString() + " ";
}
}
recvDone.Reset();
Receive(connection.current_Socket);
recvDone.WaitOne();
sendDone.Reset();
Send(connection.current_Socket, response);
sendDone.WaitOne();
closeDone.Reset();
Socket_Close(connection.current_Socket);
closeDone.WaitOne();
}
catch (Exception e)
{
Console.WriteLine("On_Connect Error: {0}", e.ToString());
Console.ReadKey(true);
}
}
public void Receive(Socket handler)
{
try{
StateObject connection = new StateObject();
connection.current_Socket = handler;
connection.current_Socket.BeginReceive(connection.data, 0, connection.data.Length, 0,
new AsyncCallback(On_Receive), connection);
}
catch (Exception e){
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
public void On_Receive(IAsyncResult asyn)
{
string content = "";
string temp = "";
StateObject connection = (StateObject)asyn.AsyncState;
Socket handler = connection.current_Socket;
int size = handler.EndReceive(asyn);
Console.WriteLine("ConnID from receive: " + connection.id);
if (size > 0)
{
temp += Encoding.ASCII.GetString(connection.data);
}
if (temp.IndexOf("<EOF>") > -1)
{
content += temp.Substring(0, temp.IndexOf("\0"));
Console.WriteLine("Read {0} bytes from socket. \nMessage: {1}", content.Length, content);
lock (connection_List)
{
foreach (StateObject conn in connection_List)
{
if (conn != connection)
{
content.Insert(0, connection.id);
response = content;
}
}
}
recvDone.Set();
}
else
{
handler.BeginReceive(connection.data, 0, connection.data.Length, 0, new AsyncCallback(On_Receive), connection);
}
}
public void Send(Socket handler, String message)
{
byte[] data = Encoding.ASCII.GetBytes(message);
handler.BeginSend(data, 0, data.Length, 0, new AsyncCallback(On_Send), handler);
}
public void On_Send(IAsyncResult result)
{
try
{
StateObject state = new StateObject();
Socket handler = (Socket)result.AsyncState;
state.current_Socket = handler;
int size = state.current_Socket.EndSend(result);
if (size > 0)
{
sendDone.Set();
}
else state.current_Socket.BeginSend(state.data, 0, state.data.Length, SocketFlags.None,
new AsyncCallback(On_Send), state);
Console.WriteLine("Bytes sent to client: {0}", size);
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine("On_Send e, error: " + e.ToString());
Console.ReadKey(true);
}
}
public void Socket_Close(Socket sock)
{
sock.LingerState = new LingerOption(true, 3);
sock.Shutdown(SocketShutdown.Both);
sock.Close();
closeDone.Set();
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
Net系统;
使用System.Net.Sockets;
使用系统线程;
公共类服务器
{
插座主插座和tcp插座;
私有静态ManualResetEvent acceptDone=新的ManualResetEvent(假);
专用静态手动复位事件sendDone=新手动复位事件(false);
专用静态ManualResetEvent recvDone=新的ManualResetEvent(错误);
专用静态手动复位事件关闭=新手动复位事件(假);
//int cl_计数=0;
列表连接_List=新列表();
私有静态字符串响应=String.Empty;
公共类状态对象
{
公共套接字当前\u Socket=null;
公共字节[]数据=新字节[256];
公共字符串id=string.Empty;
}
公共服务器()
{
服务器启动();
}
公共void服务器\u Start()
{
//创建套接字
main_tcp_Sock=新套接字(AddressFamily.InterNetwork,
SocketType.Stream,
原型(Tcp);
IPEndPoint ipLocal=新的IPEndPoint(IPAddress.Parse(“127.0.0.1”),2000年);
//绑定套接字
尝试
{
主\u tcp\u Sock.Bind(ipLocal);
WriteLine(“服务器已成功启动!”);
//开始听
主tcp_Sock.Listen(100);
while(true)
{
acceptDone.Reset();
Console.WriteLine(“等待连接…”);
//异步接受
main_tcp_Sock.beginacept(新的异步回调(在连接上),main_tcp_Sock);
acceptDone.WaitOne();
Console.WriteLine(“\n按任意按钮继续…\n\n”);
Console.ReadKey(true);
}
}
捕获(例外e)
{
Console.WriteLine(如ToString());
Console.ReadKey(true);
}
}
连接上的公共无效(IAsyncResult asyn)
{
尝试
{
套接字侦听器=(套接字)asyn.AsyncState;
套接字处理程序=listener.EndAccept(asyn);
acceptDone.Set();
StateObject连接=新建StateObject();
connection.current_Socket=处理器;
如果(!connection_List.Contains(connection))
{
锁(连接列表)
{
连接列表。添加(连接);
connection.id=“00”+connection\u List.Count.ToString()+”;
}
}
recvDone.Reset();
接收(连接、当前_插座);
recvDone.WaitOne();
sendDone.Reset();
发送(连接、当前_插座、响应);
sendDone.WaitOne();
closeDone.Reset();
插座关闭(连接、当前插座);
closeDone.WaitOne();
}
捕获(例外e)
{
WriteLine(“On_Connect错误:{0}”,e.ToString());
Console.ReadKey(true);
}
}
公共void接收(套接字处理程序)
{
试一试{
StateObject连接=新建StateObject();
connection.current_Socket=处理器;
connection.current_Socket.BeginReceive(connection.data,0,connection.data.Length,0,
新的异步回调(在接收时),连接;
}
捕获(例外e){
Console.WriteLine(如ToString());
Console.ReadKey(true);
}
}
接收时公共无效(IAsyncResult asyn)
{
字符串内容=”;
字符串temp=“”;
StateObject连接=(StateObject)asyn.AsyncState;
套接字处理程序=connection.current\u套接字;
int size=handler.EndReceive(asyn);
Console.WriteLine(“接收端的ConnID:+connection.id”);
如果(大小>0)
{
temp+=Encoding.ASCII.GetString(connection.data);
}
if(临时索引(“”>-1)
{
内容+=临时子字符串(0,临时索引(“\0”);
WriteLine(“从套接字读取{0}字节。\n消息:{1}”,content.Length,content);
锁(连接列表)
{
foreach(连接列表中的StateObject连接)
{
如果(连接!=连接)
{
content.Insert(0,connection.id);
响应=内容;
}
}
}
recvDone.Set();
}
其他的
{
handler.BeginReceive(connection.data,0,connection.data.Length,0,新异步回调(On_Receive),connection);
}
}
公共void发送(套接字处理程序、字符串消息)
{
字节[]数据=Encoding.ASCII.GetBytes(消息);
handler.BeginSend(data,0,data.Length,0,新异步回调(On_Send),handler);
}
发送时公共无效(IAsyncResult结果)
{
尝试
{
StateObject状态=新的StateObject();
套接字处理程序=(套接字)result.AsyncState;
state.current_Socket=处理程序;
int size=state.current\u Socket.EndSend(r
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
// State object for receiving data from remote device.
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousClient
{
public static int count = 0;
// The port number for the remote device.
private const int port = 2000;
// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static ManualResetEvent closeDone = new ManualResetEvent(false);
// The response from the remote device.
private static String response = String.Empty;
private static void StartClient()
{
// Connect to a remote device.
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
// Create a TCP/IP socket.
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
Start(client, remoteEP);
}
public static void Start(Socket client, EndPoint remoteEP)
{
try
{
while (true)
{
/*if (count >= 30)
{
Thread.Sleep(1000);
if (count >= 100)
{
count = 0;
Thread.Sleep(1500);
}
}*/
Console.WriteLine(count);
connectDone.Reset();
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
// Send test data to the remote device.
sendDone.Reset();
Send(client, "Some text and <EOF>");
sendDone.WaitOne();
// Receive the response from the remote device.
receiveDone.Reset();
Receive(client);
receiveDone.WaitOne();
// Write the response to the console.
Console.WriteLine("Response received : {0}", response);
// Release the socket.
closeDone.Reset();
Socket_Close(client);
closeDone.WaitOne();
++count;
}
}
catch (ObjectDisposedException)
{
Socket sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint remote = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
Start(sock, remote);
}
catch (SocketException)
{
Socket sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint remote = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port);
Start(sock, remote);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
private static void Send(Socket client, String data)
{
try
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Signal that all bytes have been sent.
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
public static void Socket_Close(Socket sock)
{
try
{
sock.LingerState = new LingerOption(true, 3);
sock.Shutdown(SocketShutdown.Both);
sock.Close();
closeDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.ReadKey(true);
}
}
public static int Main(String[] args)
{
StartClient();
return 0;
}
}
using System;
using System.Timers;
class myApp
{
public static void Main()
{
Timer myTimer = new Timer();
myTimer.Elapsed += new ElapsedEventHandler( DisplayTimeEvent );
myTimer.Interval = 1000;
myTimer.Start();
while ( Console.Read() != 'q' )
{
; // do nothing...
}
}
public static void DisplayTimeEvent( object source, ElapsedEventArgs e )
{
Console.Write("\r{0}", DateTime.Now);
}
}
private void blowTheStack(){
blowTheStack();
}
private void doSomethingUseful(){
if (!terminatingConditionReached()){
doSomethingUseful();
}
}