如何终止 Websocket 连接?

2024-05-12

如何终止 Websocket 连接?我不是在谈论关闭两端的连接,而是在“中间”中断它。我需要测试重新连接时必须发生的一些应用程序逻辑(通过 SocketIO 处理)。

不,拔掉网络电缆不算数,因为我无法在单元测试中真正实现自动化:-)此外,我希望只终止一个特定的连接,而不是全部。


这很痛苦,但这是可能的。你可以找到解释here http://www.debugging.com/bug/4715。代码如下:

using System;
using System.Collections;
using System.Runtime.InteropServices;
/// <summary>
/// This is a class for disconnecting TCP connections.
/// You can get a list of all connections and close by a connection, localIP, 
///  remoteIP, localPort and remotePort.
/// </summary>
public class Disconnecter {
        //Enumeration of the states
        public enum State{
                All=0,
                Closed=1,
                Listen=2,
                Syn_Sent=3,
                Syn_Rcvd=4,
                Established=5,
                Fin_Wait1=6,
                Fin_Wait2=7,
                Close_Wait=8,
                Closing=9,
                Last_Ack=10,
                Time_Wait=11,
                Delete_TCB=12
        }
        //Connection info
        private struct MIB_TCPROW{
                public int dwState;
                public int dwLocalAddr;
                public int dwLocalPort;
                public int dwRemoteAddr;
                public int dwRemotePort;
        }
        //API to get list of connections
        [DllImport("iphlpapi.dll")]
        private static extern int GetTcpTable(IntPtr pTcpTable,ref int pdwSize,bool bOrder);
        //API to change status of connection
        [DllImport("iphlpapi.dll")]
                //private static extern int SetTcpEntry(MIB_TCPROW tcprow);
        private static extern int SetTcpEntry(IntPtr pTcprow);
        //Convert 16-bit value from network to host byte order
        [DllImport("wsock32.dll")]
        private static extern int ntohs(int netshort);
        //Convert 16-bit value back again
        [DllImport("wsock32.dll")]
        private static extern int htons(int netshort);

        //Close all connection to the remote IP
        public static void CloseRemoteIP(string IP){
                MIB_TCPROW[] rows = getTcpTable();
                for(int i=0; i<rows.Length; i++){
                        if(rows[i].dwRemoteAddr==IPStringToInt(IP)){
                                rows[i].dwState = (int) State.Delete_TCB;
                                IntPtr ptr = GetPtrToNewObject(rows[i]);
                                int ret = SetTcpEntry(ptr);
                        }
                }
        }

        //Close all connections at current local IP
        public static void CloseLocalIP(string IP){
                MIB_TCPROW[] rows = getTcpTable();
                for(int i=0; i<rows.Length; i++){
                        if(rows[i].dwLocalAddr==IPStringToInt(IP)){
                                rows[i].dwState = (int) State.Delete_TCB;
                                IntPtr ptr = GetPtrToNewObject(rows[i]);
                                int ret = SetTcpEntry(ptr);
                        }
                }
        }
        //Closes all connections to the remote port
        public static void CloseRemotePort(int port){
                MIB_TCPROW[] rows = getTcpTable();
                for(int i=0; i<rows.Length; i++){
                        if(port==ntohs(rows[i].dwRemotePort)){
                                rows[i].dwState = (int) State.Delete_TCB;
                                IntPtr ptr = GetPtrToNewObject(rows[i]);
                                int ret = SetTcpEntry(ptr);
                        }
                }
        }
        //Closes all connections to the local port
        public static void CloseLocalPort(int port){
                MIB_TCPROW[] rows = getTcpTable();
                for(int i=0; i<rows.Length; i++){
                        if(port==ntohs(rows[i].dwLocalPort)){
                                rows[i].dwState = (int) State.Delete_TCB;
                                IntPtr ptr = GetPtrToNewObject(rows[i]);
                                int ret = SetTcpEntry(ptr);
                        }
                }
        }
        //Close a connection by returning the connectionstring
        public static void CloseConnection(string connectionstring){
                try{
                        //Split the string to its subparts
                        string[] parts = connectionstring.Split('-');
                        if(parts.Length!=4) throw new Exception("Invalid connectionstring - use the one provided by Connections.");
                        string[] loc = parts[0].Split(':');
                        string[] rem = parts[1].Split(':');
                        string[] locaddr = loc[0].Split('.');
                        string[] remaddr = rem[0].Split('.');
                        //Fill structure with data
                        MIB_TCPROW row = new MIB_TCPROW();
                        row.dwState = 12;
                        byte[] bLocAddr = new byte[]{byte.Parse(locaddr[0]),byte.Parse(locaddr[1]),byte.Parse(locaddr[2]),byte.Parse(locaddr[3])};
                        byte[] bRemAddr = new byte[]{byte.Parse(remaddr[0]),byte.Parse(remaddr[1]),byte.Parse(remaddr[2]),byte.Parse(remaddr[3])};
                        row.dwLocalAddr = BitConverter.ToInt32(bLocAddr,0);
                        row.dwRemoteAddr = BitConverter.ToInt32(bRemAddr,0);
                        row.dwLocalPort = htons(int.Parse(loc[1]));
                        row.dwRemotePort = htons(int.Parse(rem[1]));
                        //Make copy of the structure into memory and use the pointer to call SetTcpEntry
                        IntPtr ptr = GetPtrToNewObject(row);
                        int ret = SetTcpEntry(ptr);
                        if(ret==-1) throw new Exception("Unsuccessful");
                        if(ret==65) throw new Exception("User has no sufficient privilege to execute this API successfully");
                        if(ret==87) throw new Exception("Specified port is not in state to be closed down");
                        if(ret!=0) throw new Exception("Unknown error ("+ret+")");
                }catch(Exception ex){
                        throw new Exception("CloseConnection failed ("+connectionstring+")! ["+ex.GetType().ToString()+","+ex.Message+"]");
                }
        }
        //Gets all connections
        public static string[] Connections(){
                return Connections(State.All);
        }
        //Gets a connection list of connections with a defined state
        public static string[] Connections(State state){
                MIB_TCPROW[] rows = getTcpTable();

                ArrayList arr = new ArrayList();

                foreach(MIB_TCPROW row in rows){
                        if(state == State.All || state == (State)row.dwState){
                                string localaddress = IPIntToString(row.dwLocalAddr) +":"+ ntohs(row.dwLocalPort);
                                string remoteaddress = IPIntToString(row.dwRemoteAddr) + ":" + ntohs(row.dwRemotePort);
                                arr.Add(localaddress + "-" + remoteaddress + "-" + ((State)row.dwState).ToString() + "-" + row.dwState);
                        }
                }

                return (string[])arr.ToArray(typeof(System.String));
        }
        //The function that fills the MIB_TCPROW array with connectioninfos
        private static MIB_TCPROW[] getTcpTable(){
                IntPtr buffer = IntPtr.Zero; bool allocated=false;
                try{
                        int iBytes=0;
                        GetTcpTable(IntPtr.Zero, ref iBytes, false); //Getting size of return data
                        buffer=Marshal.AllocCoTaskMem(iBytes); //allocating the datasize

                        allocated=true;
                        GetTcpTable(buffer, ref iBytes, false); //Run it again to fill the memory with the data
                        int structCount=Marshal.ReadInt32(buffer); // Get the number of structures
                        IntPtr buffSubPointer = buffer; //Making a pointer that will point into the buffer
                        buffSubPointer = (IntPtr)((int)buffer + 4); //Move to the first data (ignoring dwNumEntries from the original MIB_TCPTABLE struct)
                        MIB_TCPROW[] tcpRows = new MIB_TCPROW[structCount]; //Declaring the array
                        //Get the struct size
                        MIB_TCPROW tmp = new MIB_TCPROW();
                        int sizeOfTCPROW = Marshal.SizeOf(tmp);
                        //Fill the array 1 by 1
                        for(int i=0; i<structCount; i++){
                                tcpRows[i] = (MIB_TCPROW)Marshal.PtrToStructure(buffSubPointer, typeof(MIB_TCPROW)); //copy struct data
                                buffSubPointer = (IntPtr)((int)buffSubPointer + sizeOfTCPROW ); //move to next structdata
                        }

                        return tcpRows;
                }catch(Exception ex){
                        throw new Exception("getTcpTable failed! ["+ex.GetType().ToString()+","+ex.Message+"]");
                }finally{
                        if(allocated) Marshal.FreeCoTaskMem(buffer); //Free the allocated memory
                }
        }
        private static IntPtr GetPtrToNewObject(object obj){
                IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(obj));
                Marshal.StructureToPtr(obj,ptr,false);
                return ptr;
        }
        //Convert an IP string to the INT value
        private static int IPStringToInt(string IP){
                if(IP.IndexOf(".")<0) throw new Exception("Invalid IP address");
                string[] addr = IP.Split('.');
                if(addr.Length!=4) throw new Exception("Invalid IP address");
                byte[] bytes = new byte[]{byte.Parse(addr[0]),byte.Parse(addr[1]),byte.Parse(addr[2]),byte.Parse(addr[3])};
                return BitConverter.ToInt32(bytes,0);
        }
        //Convert an IP integer to IP string
        private static string IPIntToString(int IP){
                byte[] addr = System.BitConverter.GetBytes(IP);
                return addr[0] +"."+addr[1] +"."+addr[2] +"."+addr[3];
        }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何终止 Websocket 连接? 的相关文章

随机推荐

  • 使用 Celery 通过 Gevent 进行实时、同步的外部 API 查询

    我正在开发一个 Web 应用程序 该应用程序将接收用户的请求 并且必须调用许多外部 API 来编写对该请求的答案 这可以直接从主 Web 线程使用 gevent 之类的东西来扇出请求来完成 或者 我在想 我可以将传入的请求放入队列中 并使用
  • Chrome 扩展程序可有效阻止域名

    我正在制作一个非常简单的 Chrome 扩展来阻止对某些域的请求 厌倦了许多网站上缓慢的页面加载 等待 Facebook 垃圾 我的问题是关于如何有效加载用户指定的域列表 这Chrome 文档 https developer chrome
  • 配置 github 以使用其他文件作为 README

    由于 Eclipse 和 EGit 组织文件和目录的方式不同 我的 README md 文件并不位于 git 存储库的根目录中 而是位于更深的一个文件夹中 我怎样才能告诉github显示some folder README md作为项目的自
  • 当 AngularJS 表单无效时禁用提交按钮

    我的表格是这样的
  • 如何解释“错误C2018:未知字符'0x40'?[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 在编译一些代码时 我收到以下信息 错误 C2018 未知字符 0x40 我想知道如何解决这样的问题 这是我要开始的地方
  • 如何找出当前正在运行的 PHP 可执行文件?

    在 PHP 程序内部 我想知道执行它的二进制文件的位置 Perl 有 X以此目的 PHP 中有等效的吗 这样它就可以使用自身执行子 PHP 进程 而不是硬编码路径或假设 php 是正确的 UPDATE 我使用的是lighttpd FastC
  • 启动客户端时,代码要求提供电话/机器人令牌

    使用 Telethon 库运行我的第一个代码时 它要求提供机器人令牌 这是实际的代码 from telethon import TelegramClient events sync api id 1234567 api hash xxxxx
  • pgAdmin 4 v3.0 查询工具初始化错误

    我最近买了一台新笔记本电脑并下载了 pgAdmin 4 v3 0 在此之前 我一直在运行 pgAdmin 4 v2 0 没有任何问题 但是 现在每当我尝试打开查询工具 仅通过下拉工具菜单 时 我都会收到错误消息 查询工具初始化错误 在最初的
  • jwplayer - 如何在播放前获取视频时长?

    我试图在 jwplayer 开始播放之前获取视频的持续时间 我尝试在onReady事件回调中调用getDuration 但它返回 1 当我在 onPlay 事件回调中调用 getDuration 时 我得到了正确的值 有任何想法吗 这是我的
  • 我应该使用多个 HttpClient 来进行批量异步 GET 请求吗?

    我有一个场景 我需要在尽可能短的时间内发出大量 GET 请求 想想大约 1000 个 我知道通常最好保留一个客户端并尽可能重用它 Create Single HTTP Client HttpClient client new HttpCli
  • 反转比例函数

    这对我来说很有趣 看下面的D3代码 var scale d3 scale linear domain 100 500 range 10 350 scale 100 Returns 10 scale 300 Returns 180 scale
  • Tensorflow `tf.layers.batch_normalization` 不会向 `tf.GraphKeys.UPDATE_OPS` 添加更新操作

    以下代码 复制 粘贴可运行 说明了如何使用tf layers batch normalization import tensorflow as tf bn tf layers batch normalization tf constant
  • 使用普通用户和 https 的 gitea

    我正在尝试设置 gitea 以使用 https 和我从 LetsEncrypt 获得的证书 运行该服务作为普通用户 我已经让它与普通用户在端口 80 上使用 http 一起工作git并使用 iptables 将端口 80 重定向到端口 30
  • 滚动视图下的iOS swift 4 imageview:双击缩小

    我已经应用了图像视图来通过捏合来放大 缩小 那很容易 当在图像视图上应用双击时 无法检测到选择方法 我使用 Xcode 9 和 swift 4 您能告诉我滚动视图是否应该应用双击手势吗 var previewImage UIImage ni
  • Facebook Javascript SDK - 查询个人资料图片

    我正在尝试通过 Javascript SDK 查询个人资料图片 I do 不想要图表 api 链接 我想得到src big link 我有以下代码 FB api me fields id name picture function resp
  • F# nameof 运算符不是一等函数

    我正在使用 F 4 7
  • Android 和 iPhone 应用程序可以使用同一个 Facebook 应用程序 ID 吗?

    我有两个具有相同名称和相同功能的应用程序 一款在安卓市场 一款在应用商店 目前仅通过 iPhone 应用程序 您可以使用我创建的 Facebook 应用程序将您的分数发布到 Facebook 墙上 我的问题是我可以使用相同的 Android
  • 列的 SQL MAX(包括其主键)

    Short 从下面的 sql select 中 我获取了 cart id 和该购物车中最高价值商品的值 SELECT CartItems cart id MAX ItemValues value FROM CartItems INNER J
  • Listview里面只有一个Element

    您好 我正在尝试将列表视图放入列表视图中的列表视图中 唯一的问题是只有第一个列表视图正确显示所有元素 此后的每个列表视图仅包含一个元素 UPDATE 创建我自己的不可滚动列表视图解决了这个问题 https stackoverflow com
  • 如何终止 Websocket 连接?

    如何终止 Websocket 连接 我不是在谈论关闭两端的连接 而是在 中间 中断它 我需要测试重新连接时必须发生的一些应用程序逻辑 通过 SocketIO 处理 不 拔掉网络电缆不算数 因为我无法在单元测试中真正实现自动化 此外 我希望只