下面的代码是从网找到的,能正常运行没有问题,我有一些问题:
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;
}
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;
}
然后看代码
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()就行了
我向服务器发送信息,提示 state.client = server.EndAcceptTcpClient(ar); 这行出错。下面的是具体的错误信息
未处理 System.ObjectDisposedException
Message="无法访问已释放的对象。\r\n对象名:“System.Net.Sockets.Socket”。"
Source="System"
ObjectName="System.Net.Sockets.Socket"
StackTrace:
在 System.Net.Sockets.Socket.EndAccept(IAsyncResult asyncResult)
在 System.Net.Sockets.TcpListener.EndAcceptTcpClient(IAsyncResult asyncResult)
在 SocketServer_Async.ServerForm.AcceptCallback(IAsyncResult ar) 位置 D:\xxx\应用程序服务\SocketSample\SocketServer_Async\SocketServer_Async\ServerForm.cs:行号 52
在 System.Net.LazyAsyncResult.Complete(IntPtr userToken)
在 System.Net.ContextAwareResult.CompleteCallback(Object state)
在 System.Threading.ExecutionContext.runTryCode(Object userData)
在 System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Net.ContextAwareResult.Complete(IntPtr userToken)
在 System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
在 System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
在 System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)