首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

关于socket服务用异步方式的有关问题

2012-01-08 
关于socket服务用异步方式的问题。下面的代码是从网找到的,能正常运行没有问题,我有一些问题:1、TcpListener

关于socket服务用异步方式的问题。
下面的代码是从网找到的,能正常运行没有问题,我有一些问题:
1、TcpListener server 这些变量都是局部的,为什么还能正常工作。
2、我如何停止监听服务。

private void AcceptCallback(IAsyncResult ar) 
  { 
  TcpListener server = (TcpListener)ar.AsyncState; 
  ClientState state = new ClientState(); 

  // Once the accept operation completes, this callback will 
  // be called. In it, you can create a new TcpClient in much 
  // the same way you did it in the synchronous code you had: 

  state.client = server.EndAcceptTcpClient(ar); 

  // We're going to start reading from the client's stream, and 
  // we need a buffer for that: 

  state.buffer = new byte[4096]; 

  // Note that the TcpClient and the byte[] are both put into 
  // this "ClientState" object. We're going to need an easy 
  // way to get at those values in the callback for the read 
  // operation. 

  // Next, start a new accept operation so that we can process 
  // another client connection: 

  server.BeginAcceptTcpClient(AcceptCallback, server); 

  // Finally, start a read operation on the client we just 
  // accepted. Note that you could do this before starting the 
  // accept operation; the order isn't really important. 

  state.client.GetStream().BeginRead(state.buffer, 0,state.buffer.Length, ReadCallback, state); 
  } 

  private void ReadCallback(IAsyncResult ar) 
  { 
  ClientState state = (ClientState)ar.AsyncState; 
  int cbRead = state.client.GetStream().EndRead(ar); 

  if (cbRead == 0) 
  { 
  // The client has closed the connection 
  return; 
  }
  // Your data is in state.buffer, and there are cbRead 
  // bytes to process in the buffer. This number may be 
  // anywhere from 1 up to the length of the buffer. 
  // The i/o completes when there is _any_ data to be read, 
  // not necessarily when the buffer is full. 

  // So, for example: 下面的是我的实现。
  SockMsgStruct message = new SockMsgStruct();
  message = (SockMsgStruct)ZhiKe.Serialization.ByteToObj(state.buffer);

  StreamWriter f = new StreamWriter("c:/aa.txt",true);
  f.WriteLine(message.MsgUid);
  f.WriteLine(message.sMsg);
  f.WriteLine(message.iMsgType);
  f.Flush();
  f.Close();
  //textBox1.Text = textBox1.Text + strData + "/n/r";

  // For ASCII you won't have to worry about partial characters 
  // but for pretty much any other common encoding you'll have to 
  // deal with that possibility, as there's no guarantee that an 
  // entire character will be transmitted in one piece. 

  // Of course, even with ASCII, you need to watch your string 
  // terminations. You'll have to either check the read buffer 
  // directly for a null terminator, or have some other means 


  // of detecting the actual end of a string. By the time the 
  // string goes through the decoding process, you'll have lost 
  // that information. 

  // As with the accept operation, we need to start a new read 
  // operation on this client, so that we can process the next 
  // bit of data that's sent: 

  state.client.GetStream().BeginRead(state.buffer, 0,state.buffer.Length, ReadCallback, state);
  } 

  private void button1_Click(object sender, EventArgs e)
  {
  Int32 port = int.Parse(txtPort.Text);
  IPAddress localAddr = IPAddress.Parse(cmbAddress.Text);
  TcpListener server = new TcpListener(localAddr, port);
  server.Start();
  // The above is pretty much what you had, cleaned up 
  // a bit. All you have to do at this point is start 
  // an accept operation: 
  server.BeginAcceptTcpClient(AcceptCallback, server); 
  }


  class ClientState
  {
  public TcpClient client;
  public byte[] buffer;
  }

[解决办法]
button1_Click里面创建TcpListener server ,然后使用异步回调AcceptCallback,“server.BeginAcceptTcpClient(AcceptCallback, server);”它带一个 IAsyncResult 类型的参数,就是说server 对象已经含在这个参数里了。 
 然后看代码
AcceptCallback(IAsyncResult ar)
{
TcpListener server = (TcpListener)ar.AsyncState;
这里,又从参数里把server 对象取出来了。

至于关闭监听的问题,
private void button1_Click(object sender, EventArgs e) 

Int32 port = int.Parse(txtPort.Text); 
IPAddress localAddr = IPAddress.Parse(cmbAddress.Text); 
TcpListener server = new TcpListener(localAddr, port); 
你改成
TcpListener server =null;
private void button1_Click(object sender, EventArgs e) 

Int32 port = int.Parse(txtPort.Text); 
IPAddress localAddr = IPAddress.Parse(cmbAddress.Text); 
server = new TcpListener(localAddr, port); 
...
}
最后需要关闭的时候,使用server .close()就行了
[解决办法]
这个异常是在关闭TCPListener时一定会引发的,你必须捕获并处理它。

热点排行