ASP.NET 在线程里面做了一个TCP发送数据,三秒钟发一次,当我不想发送时,销毁线程居然停止不了数据发送

作者&投稿:汝盆 (若有异议请与网页底部的电邮联系)
asp.net 用TCP发送数据时, 线程已经销毁为什么数据依然持续发送~

发送数据时,

这个问题好像早了点儿,估计你已经解决了吧
我正好查相关问题,看到你的页面,顺嘴说一句:IIS-应用程序池-高级属性里有个闲置超时设置,系统默认是20分钟,你看看自动停止的时长是不是20分钟,如果是的话,可能跟这个有关系。另外我的IIS不知道是不是IIS6版本的,仅供你参考。

这是我网络中找的参考,希望对你有帮助。
在多线程任务中,TCP任务通过三次握手能建立可靠的连接,但是经常会发生在数据传输或通信时发生网络突然断开或者长时间连接空循环监听而未进行操作,需要在软件设计时考虑程序运行中检测到服务器对客户端的这一“虚连接”现象。

如果主机崩溃,write是否阻塞取决于内核的tcp缓冲区,但read将一直阻塞,直到超时ETIMEOUT,或由于某些中间路由器的原因返回EHOSTUNREACH/ENETUNREACH。select不能检测到该情况。
如果主机崩溃并重起,客户的write到达主机时主机响应RST,客户的read将返ECONNRESET。
此处的”非正常断开”指TCP连接不是以优雅的方式断开,如网线故障等物理链路的原因,还有突然主机断电等原因


心跳机制

有两种方法可以检测:1.TCP连接双方定时发握手消息
2.利用TCP协议栈中的KeepAlive探测
第二种方法简单可靠,只需对TCP连接两个Socket设定KeepAlive探测,所以本文只讲第二种方法在Linux,Window2000下的实现(在其它的平台上没有作进一步的测试)

1)Windows平台

C代码

//定义结构及宏

struct TCP_KEEPALIVE {

u_longonoff;

u_longkeepalivetime;

u_longkeepaliveinterval;

} ;

#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)

//KeepAlive实现

TCP_KEEPALIVE inKeepAlive = {0}; //输入参数

unsigned long ulInLen = sizeof(TCP_KEEPALIVE);

TCP_KEEPALIVE outKeepAlive = {0}; //输出参数

unsigned long ulOutLen = sizeof(TCP_KEEPALIVE);

unsigned long ulBytesReturn = 0;

//设置socket的keep alive为5秒,并且发送次数为3次

inKeepAlive.onoff = 1;

inKeepAlive.keepaliveinterval = 5000; //两次KeepAlive探测间的时间间隔

inKeepAlive.keepalivetime = 5000; //开始首次KeepAlive探测前的TCP空闭时间

if (WSAIoctl((unsigned int)s, SIO_KEEPALIVE_VALS,

(LPVOID)&inKeepAlive, ulInLen,

(LPVOID)&outKeepAlive, ulOutLen,

&ulBytesReturn, NULL, NULL) == SOCKET_ERROR)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT ("(%P|%t) \WSAIoctl failed. error code(%d)!\n"), WSAGetLastError()));

}
//定义结构及宏 struct TCP_KEEPALIVE { u_longonoff; u_longkeepalivetime; u_longkeepaliveinterval; } ; #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) //KeepAlive实现 TCP_KEEPALIVE inKeepAlive = {0}; //输入参数 unsigned long ulInLen = sizeof(TCP_KEEPALIVE); TCP_KEEPALIVE outKeepAlive = {0}; //输出参数 unsigned long ulOutLen = sizeof(TCP_KEEPALIVE); unsigned long ulBytesReturn = 0; //设置socket的keep alive为5秒,并且发送次数为3次 inKeepAlive.onoff = 1; inKeepAlive.keepaliveinterval = 5000; //两次KeepAlive探测间的时间间隔 inKeepAlive.keepalivetime = 5000; //开始首次KeepAlive探测前的TCP空闭时间 if (WSAIoctl((unsigned int)s, SIO_KEEPALIVE_VALS, (LPVOID)&inKeepAlive, ulInLen, (LPVOID)&outKeepAlive, ulOutLen, &ulBytesReturn, NULL, NULL) == SOCKET_ERROR) { ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%P|%t) \WSAIoctl failed. error code(%d)!\n"), WSAGetLastError())); }

2)Linux平台

C代码

#include

……

////KeepAlive实现

//下面代码要求有ACE,如果没有包含ACE,则请把用到的ACE函数改成linux相应的接口

int keepAlive = 1;//设定KeepAlive

int keepIdle = 5;//开始首次KeepAlive探测前的TCP空闭时间

int keepInterval = 5;//两次KeepAlive探测间的时间间隔

int keepCount = 3;//判定断开前的KeepAlive探测次数

if(setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,(void*)&keepAlive,sizeof(keepAlive)) == -1)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT ("(%P|%t) setsockopt SO_KEEPALIVE error!\n")));

}

if(setsockopt(s,SOL_TCP,TCP_KEEPIDLE,(void *)&keepIdle,sizeof(keepIdle)) == -1)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPIDLE error!\n")));

}

if(setsockopt(s,SOL_TCP,TCP_KEEPINTVL,(void *)&keepInterval,sizeof(keepInterval)) == -1)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT ("(%P|%t) setsockopt TCP_KEEPINTVL error!\n")));

}

if(setsockopt(s,SOL_TCP,TCP_KEEPCNT,(void *)&keepCount,sizeof(keepCount)) == -1)

{

ACE_DEBUG ((LM_INFO,

ACE_TEXT ("(%P|%t)setsockopt TCP_KEEPCNT error!\n")));

}

心跳机制:定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性。

网络中的接收和发送数据都是使用WINDOWS中的SOCKET进行实现。但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题。可是如何判断这个套接字是否还可以使用呢?这个就需要在系统中创建心跳机制。其实TCP中已经为我们实现了一个叫做心跳的机制。如果你设置了心跳,那TCP就会在一定的时间(比如你设置的是3秒钟)内发送你设置的次数的心跳(比如说2次),并且此信息不会影响你自己定义的协议。所谓“心跳”就是定时发送一个自定义的结构体(心跳包或心跳帧),让对方知道自己“在线”。以确保链接的有效性。

  所谓的心跳包就是客户端定时发送简单的信息给服务器端告诉它我还在而已。代码就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息如果服务端几分钟内没有收到客户端信息则视客户端断开。比如有些通信软件长时间不使用,要想知道它的状态是在线还是离线就需要心跳包,定时发包收包。发包方:可以是客户也可以是服务端,看哪边实现方便合理。一般是客户端。服务器也可以定时轮询发心跳下去。心跳包之所以叫心跳包是因为:它像心跳一样每隔固定时间发一次,以此来告诉服务器,这个客户端还活着。事实上这是为了保持长连接,至于这个包的内容,是没有什么特别规定的,不过一般都是很小的包,或者只包含包头的一个空包。在TCP的机制里面,本身是存在有心跳包的机制的,也就是TCP的选项。系统默认是设置的是2小时的心跳频率。但是它检查不到机器断电、网线拔出、防火墙这些断线。而且逻辑层处理断线可能也不是那么好处理。一般,如果只是用于保活还是可以的。心跳包一般来说都是在逻辑层发送空的包来实现的。下一个定时器,在一定时间间隔下发送一个空包给客户端,然后客户端反馈一个同样的空包回来,服务器如果在一定时间内收不到客户端发送过来的反馈包,那就只有认定说掉线了。只需要send或者recv一下,如果结果为零,则为掉线。但是,在长连接下,有可能很长一段时间都没有数据往来。理论上说,这个连接是一直保持连接的,但是实际情况中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。在获知了断线之后,服务器逻辑可能需要做一些事情,比如断线后的数据清理呀,重新连接呀当然,这个自然是要由逻辑层根据需求去做了。总的来说,心跳包主要也就是用于长连接的保活和断线处理。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒。

TCP连接异常断开后操作系统会告诉你,你查询套接字的状态会得到异常,或者当发现函数失败WSAGetLastError的时候也会得到内核的通知。

// 发送回应消息
int nSend = Send4IntMsg(sock, (char*)(LPCTSTR)strSendBuf,
strSendBuf.GetLength(), errMsg);
if (nSend < 0) //
发送消息失败
closesocket(sock);//重新连接

在B/S编程和UDP编程时才用到心跳。比如定期向web服务器发一个request证明自己在线。http协议是请求一下就断开了,每次都要重新连接,重新请求,这种情况下才有必要用心跳机制。一般的TCP通信都是长连接,不可能频繁连接和断开。对于长期保持连接的情况,一旦断开,操作系统底层都会通知你,你需要解决的是如何获取到系统的通知。


抚州市19687664067: asp.net中做了一个访问phonefile文件夹时跳转至继承IHttpHandler的类然后重定向到phone相印的路径,在本地配置是成功的,但是发布到iis后web.config的配置就不起作用了,直接抛出404找不到phonefile里面的文件<add verb="*"
佟涛人乙: 其实我是提问人哈,该死的问问不支持自己贴答案.我之前在本地的做法是configuration>system.web>httpHandlers下增加了一个节点<add verb="请求方式" path="请求路径支持通配符" type="类名"/>配置文件中增加如上虽然说在本地测试...

抚州市19687664067: asp.net文件复制进度条实现asp.net做了一个站点升级的
佟涛人乙: 1.计算文件总个数(或者总大小)2.使用新线程拷贝文件3设置全局变量存储拷贝数目4.新建Timer每秒监视该数目,使用委托控制progressbar进度即可. 后台: ...

抚州市19687664067: 用asp.net写好的一个程序如何在本地运行? -
佟涛人乙: 这是复制网上的一个做法看能不能用 第一步:安装IIS:win98系统:安装PWS,正确安装完后,在浏览器地址栏里输入:http://127.0.0.1就会看到一个界面,如果安装不正确,将没有内容显示.win200以上版本操作系统:插入系统安装光盘,或者...

抚州市19687664067: 用asp.net 做好了一个网站,怎么发布? 请具体的讲讲每个方面和步骤.谢谢.回答的好,会加分的. -
佟涛人乙: 在解决方案资源管理器中,右键点击项目名称,选择“生成”进行编译,再次右击项目名称,选择“发布···”,弹出“发布Web”对话框,你只要指定好发布文件夹地址就好了,下面的默认设置不需要懂.至于发布到网上,可以用IIS发布到局域网上,在控制面板中打开“管理工具”,双击“Internet 信息服务(IIS)管理器”,在左侧的“连接”里面,把树目录打开,右击“网站”,选择“添加网站”,填写网站名称、物理路径(就是刚才发布的那个文件夹的路径),绑定类型为http,IP地址的下拉按钮自动包含当前主机的IP地址,选择它就行了,端口默认为80,主机名可以不写,访问时直接在浏览器地址栏输入IP地址就行了.

抚州市19687664067: asp.net的问题,以前在程序A里面写好了一个类,现在要在程序B里面调用这个类,要怎样才能调用到? -
佟涛人乙: 把A编译为DLL在B添加引用然后在页面using进去A的命名空间就OK了

抚州市19687664067: 做好的ASP.NET程序如何在其它电脑上运行 -
佟涛人乙: 情况1 如果对方也有VS,则很简单,那过去打开网站就可以运行了,数据库放在APP_DATA内,不要变,配置文件自动会识别 情况2 首先:如果对方没有VS,则安装IIS,在装好IIS以及.NETFRAMEWORK2.0或者3.0之后,打开IIS,建立网站,根据导航选择到你文件所在的文件夹 其次:安装SQLSERVER2005或者2008或者2000,根据你自己的版本来决定,建立一个新的数据库,使用APP_DATA里面的数据库文件. 最后:修改配置文件,使得数据库连接与SQLSERVER中的设置相同就可以了说的比较简单,如有需要直接问我

抚州市19687664067: 在asp.net(vb)中做了一个登陆界面,在dreamweaver中制作了登陆后要显示的index.html页面.如何连接? -
佟涛人乙: 把你制作好的index.html放入工程目录中 在程序中调用登录按钮的点击方法; Response.Redirect(“\路径”)方法.

抚州市19687664067: net 中多线程有几种实现方法 -
佟涛人乙: 1:UI线程.这个线程是操作系统自动创建的,你画了个winform,那么程序一启动,自然有了这么个线程.值得注意的是,你添加一个Timer控件,现实的多线程,实际上,依然在UI线程里.只是定时被Timer夺去控制权而已,本质上依然是单线程...

抚州市19687664067: 我在ASP.net项目中建立一个全局应用程序类为什么不掉进App - GlobalResources这里面? -
佟涛人乙: 1. 全局类通常放在app_code下,这个需要你手动建立右键项目add asp.net folder2. 你现在的文件夹主要放置文字(比如全球化等字符串资源的)

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网