标题:c# TcpListener做服务器问题
只看楼主
pan973
Rank: 1
等 级:新手上路
帖 子:19
专家分:0
注 册:2009-4-24
结帖率:66.67%
已结贴  问题点数:10 回复次数:3 
c# TcpListener做服务器问题
本人是个新手。第一次用TcpListener做服务器。发现一个问题。当服务器监听端口时,客户端断开时在网络连接处还可以看到原本客户端连接的信息。当新的客户端连接时又出现一个新的连接,在此我想知道如何去掉之前的客户端连接。。因为我是新手。各位大大能不能帮我看看我的程序那儿出了问题。最好能有程序上来
以下是我编的程序(本人不会异步。所以用了同步的)
//定义
delegate void AddString_del(string str);
  AddString_del addDel;//该代理用于向接收窗体添加数据
Thread thListen;//监听线程
  TcpClient tcpClient;
  TcpListener serverListener;
  bool islian = false;
#region 点击GPRS打开事件
  /// <summary>
  /// 点击GPRS打开事件
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void btnOpenGPRS_Click(object sender, EventArgs e)//
  {
  IPAddress serverIp=null;
  int port = 0;
  serverIp = IPAddress.Parse(this.IP.Text.ToString());
  port = Convert.ToInt32(this.port.Text.ToString());
  IPEndPoint local = new IPEndPoint(serverIp, port);
  serverListener = new TcpListener(local);
  serverListener.Start();
  //
  thListen = new Thread(new ThreadStart(ServerListen));
  thListen.Start();
  }
  #endregion

  #region 监听GPRS客户端
  /// <summary>
  /// 监听GPRS客户端
  /// </summary>
  private void ServerListen()
  {

  while (true)
  {
  tcpClient = serverListener.AcceptTcpClient();
  Thread tcpthread = new Thread(DoSomeThing);//创建新线程,这样程序可以立刻进入下一次while循环,处理新的客户端接入
  tcpthread.Start(tcpClient);//把新获得的连接作为参数传过去(其实也可以不传,因为你的tcpClient是全局的)
  }
  }
  #endregion

  #region 为每一个客户端接入创建的处理线程
  ///
  ///为每一个客户端接入创建的处理线程
  ///
  private void DoSomeThing(object parmater)
  {
  TcpClient newTcpClient = parmater as TcpClient;//将参数转换成TcpClinet  
  int a = 0;
  byte[] buffer = new byte[1024];

  NetworkStream stream = newTcpClient.GetStream(); //

  if (newTcpClient.Connected)
  {
  islian = true;
  }
  else
  {
  islian = false;
  }
  while (islian)
  {
  //Thread.Sleep(1000);
  try
  {

  a = stream.Read(buffer, 0, 1024);
  string temp = "", message = "";
  if (a > 0)
  {
  islian = true;
  temp = System.Text.Encoding.ASCII.GetString(buffer, 0, a);
  // message += temp;

  message = Encoding.ASCII.GetString(buffer, 0, a);
  textBox111.Invoke(addDel, temp + "\n");
  //MessageBox.Show("接收到" + message);   
  stream.Flush();


  }
  else
  {
  islian = false;
  newTcpClient.Close();
  break;
  //stream.Flush();
  //MessageBox.Show("断开");

  }


  //stream.Close();//这个如果使用的话,服务器一接到数据,客户端就会被关掉  
  }
  catch (Exception)
  {
  //TODO:接收数据线程异常处理  
  if (newTcpClient != null)
  {
  newTcpClient.Close();
  }
  islian = false;
  //MessageBox.Show(ex.Message+"cuowu");
  //textBox3.Invoke(addDel, ex.Message);
  break;

  }
  }

  }
  #endregion
以上就是我所编的程序。。真的不知道如何在客户端断开后关闭连接。。希望有人能帮看看问题出在那儿
搜索更多相关主题的帖子: TcpListener 服务器 
2010-08-14 15:22
pan973
Rank: 1
等 级:新手上路
帖 子:19
专家分:0
注 册:2009-4-24
得分:0 
有人能帮忙吗?很纠结
2010-08-16 11:04
烟雨袅袅
Rank: 6Rank: 6
来 自:星空雨际
等 级:侠之大者
威 望:1
帖 子:430
专家分:494
注 册:2007-11-26
得分:5 
以下是引用pan973在2010-8-16 11:04:09的发言:

有人能帮忙吗?很纠结
我是用异步使现的,也无法去掉原先的连接,纠结中………………
不过好像可以用Socket类的IOControl()函数,据说2小时后如果没有连接,会自动断开连接,可以修改默认值让它1分后断开,我是没试过,不知道行不行
但是我在实际应用中发现,MSDN说的这种处理方法在很多时候根本无效,无法检测出网络已经异常断开了。那我们该怎么办呢?

  我们知道,TCP有一个连接检测机制,就是如果在指定的时间内(一般为2个小时)没有数据传送,会给对端发送一个Keep-Alive数据报,使用的序列号是曾经发出的最后一个报文的最后一个字节的序列号,对端如果收到这个数据,回送一个TCP的ACK,确认这个字节已经收到,这样就知道此连接没有被断开。如果一段时间没有收到对方的响应,会进行重试,重试几次后,向对端发一个reset,然后将连接断掉。

  在Windows中,第一次探测是在最后一次数据发送的两个小时,然后每隔1秒探测一次,一共探测5次,如果5次都没有收到回应的话,就会断开这个连接。但两个小时对于我们的项目来说显然太长了。我们必须缩短这个时间。那么我们该如何做呢?我要利用Socket类的IOControl()函数。我们来看看这个函数能干些什么:
具体见网页http://

2010-08-16 15:29
bygg
Rank: 16Rank: 16Rank: 16Rank: 16
来 自:乖乖的心中
等 级:版主
威 望:241
帖 子:13555
专家分:3076
注 册:2006-10-23
得分:5 
Send_Completed(object sender, SocketAsyncEventArgs e)

var client = e.UserToken as UserObject;
if (e.BytesTransferred==0)  //如果传输的数据量为0,则表示链接已经断开
{

    client.Socket.Close();
}

参考一下./


飘过~~
2010-08-16 16:22



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-315679-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.438772 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved