求助MSDN中关于C#异步SOCKET服务端示例的问题

jy251 2008-11-14 11:51:19


public class StateObject {
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}

public class AsynchronousSocketListener {

public static string data = null;
public static ManualResetEvent allDone = new ManualResetEvent(false);

public AsynchronousSocketListener() {
}

public static void StartListening() {
byte[] bytes = new Byte[1024];

IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

Socket listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );

try {
listener.Bind(localEndPoint);
listener.Listen(100);

while (true) {
allDone.Reset();

Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(
new AsyncCallback(AcceptCallback),
listener );

allDone.WaitOne();
}

} catch (Exception e) {
Console.WriteLine(e.ToString());
}

Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}

public static void AcceptCallback(IAsyncResult ar) {
allDone.Set();

Socket listener = (Socket) ar.AsyncState;
Socket handler = listener.EndAccept(ar);

StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}

public static void ReadCallback(IAsyncResult ar) {
String content = String.Empty;
StateObject state = (StateObject) ar.AsyncState;
Socket handler = state.workSocket;

int bytesRead = handler.EndReceive(ar);

if (bytesRead > 0) {
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));

content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1) {
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content );
Send(handler, content);
} else {
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}

private static void Send(Socket handler, String data) {
byte[] byteData = Encoding.ASCII.GetBytes(data);

handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}

private static void SendCallback(IAsyncResult ar) {
try {
Socket handler = (Socket) ar.AsyncState;

int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);

handler.Shutdown(SocketShutdown.Both);
handler.Close();

} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}


public static int Main(String[] args) {
StartListening();
return 0;
}
}



以上是MSDN中关于异步SOCLET服务端的代码,我的问题是:
在服务端监听到了一个客户端连接后,将在AcceptCallback函数中创建用户处理这个客户端的对象。并且指定ReadCallback为处理接收的回调函数。
那么ReadCallback函数中的函数过程是否是线程安全的??比如说:如果第一个客户端连接上来了,并且正在ReadCallback中处理,并且在短时间之内不会结束处理。第2个客户端这时候连接上来了,那么第2个客户端的处理是会等待第一个执行完毕之后才进入ReadCallback呢?还是直接也进入ReadCallback??如果第2个客户端也进入ReadCallback进行处理了,那么会将第一个客户端的数据冲掉吗??
另外C#中回调函数的处理机制是否是另外启动一个新的线程?即是否是调用这个回调一次,就会启动一个新的线程来处理这个回调?不过回调也是委托,按照道理来说,应该不会重新启动一个线程的。并且两次调用回调,那么调用的应该是同一个线程中的统一个回调吧。

这个问题困惑了我很久了····请大家帮忙解惑。。。
刚上论坛不久,分不多,请见谅~~~~
...全文
602 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
jy251 2008-11-17
  • 打赏
  • 举报
回复
谢谢各位,现在给分
jy251 2008-11-15
  • 打赏
  • 举报
回复
谢谢两位的回答,但是我还是没弄明白。

其实所谓的异步也只不过是说第2个不用等待第1个处理完毕再处理。这段代码的异步是通过回调和阻塞实现的,相信大部分的异步都是这样实现的。

就多个客户端同时对一个服务端访问来说,我关心的只是服务端这边的处理过程是否是线程安全的,会不会因为第2个客户端或者第N个客户端的介入,而导致之前客户端的处理被覆盖掉。

想了半天,还是这样的结论:
服务端的SOCKET我封装在一个类中,这些方法都不在是Static的,那么针对同一个服务端的SOcket对象来说,这个回调函数没有被调用完毕之前是不会被再次调用的。。。

也不知道我理解的是否正确,明天结贴给分咯······

还是先等等更好的回答。
长沙三毛 2008-11-15
  • 打赏
  • 举报
回复
所有的异步操作,都将在一个独立的线程中完成(该结论出自哪本书忘记了),所以异步操作总是多线程的。
xu_2007 2008-11-14
  • 打赏
  • 举报
回复
同意楼上所说的,即然叫异步的所以不管是连接,还是发送数据或接收数据都是异步的,所以应该不存在等待这个问题~!
zmj1563 2008-11-14
  • 打赏
  • 举报
回复
我是这样理解的,第2个客户端的处理是不会等待第1个客户端的 多个客户端与服务端的通信是同时进行的~~~~~如果要等待的话那就是Socket同步传输了.

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧