欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#利用 HttpWebRequest 类发送post请求,出现“套接字(协议/网络地址/端口)只允许使用一次”问题

程序员文章站 2022-04-28 13:08:45
声明:问题虽然已经被解决,但是并没有明白具体原理,欢迎大佬补充。 最近网站出现一个问题,在C#里面使用 HttpWebRequest 类去发送post请求,偶尔 会出现 “套接字(协议/网络地址/端口)只允许使用一次” 的异常,很明显应该是端口被占用。 原因排查: 1、网上说最多就是其他程序占用端口 ......

声明:问题虽然已经被解决,但是并没有明白具体原理,欢迎大佬补充。

 

最近网站出现一个问题,在c#里面使用  httpwebrequest 类去发送post请求,偶尔 会出现 “套接字(协议/网络地址/端口)只允许使用一次” 的异常,很明显应该是端口被占用。

原因排查:

1、网上说最多就是其他程序占用端口:因为已经上线,并且有时候可以正常运行,因此排除其他程序占用端口的可能,而且我网站用的就是80端口。 

2、第二个可能原因就是接口性能较差,占用较长处理时间:我 给post的目标接口(因为接口也是本身网站提供的,因此可以进行监控) 加上时间日志,发现处理时长都在 30ms -50 ms 左右,而且网站访问量并不是很大,因此这个处理速度还是非常快的,按理说不应该出现端口占用情况。

 

我们现在来看一下post代码 ,如下:

private string sendhttpwebrequest(bool ispost, string senddata, string requesturl)
    {
        utf8encoding encoding = new utf8encoding();
        byte[] data = encoding.getbytes(senddata);
        // 制备web请求
        httpwebrequest myrequest = (httpwebrequest)webrequest.create(requesturl);
        if (ispost)
        {
            myrequest.method = "post";
        }
        else
        {
            myrequest.method = "get";
        }
        myrequest.contenttype = "application/x-www-form-urlencoded";
        myrequest.contentlength = data.length;
        if (ispost)
        {
            stream newstream = myrequest.getrequeststream();
            newstream.write(data, 0, data.length);
            newstream.close();
        }
    }

 

最后 我发现上面的代码并没有接收返回,是因为这个接口本身设计的问题,接口只是为了通知,并不关心返回结果(当然这本身不是一个好的设计) 。

但是经过测试,问题就出在没有接收返回上,加上接收返回的代码以后, “套接字(协议/网络地址/端口)只允许使用一次” 的异常就消失 了!

最后post代码如下:

private string sendhttpwebrequest(bool ispost, string senddata, string requesturl)
    {
        utf8encoding encoding = new utf8encoding();
        byte[] data = encoding.getbytes(senddata);
        // 制备web请求
        httpwebrequest myrequest = (httpwebrequest)webrequest.create(requesturl);
        if (ispost)
        {
            myrequest.method = "post";
        }
        else
        {
            myrequest.method = "get";
        }
        myrequest.contenttype = "application/x-www-form-urlencoded";
        myrequest.contentlength = data.length;
        if (ispost)
        {
            stream newstream = myrequest.getrequeststream();
            newstream.write(data, 0, data.length);
            newstream.close();
        }
   //获取响应
  httpwebresponse myresponse = (httpwebresponse)myrequest.getresponse();
  streamreader reader = new streamreader(myresponse.getresponsestream(), encoding.default);
   return reader.readtoend();
}

到此, “套接字(协议/网络地址/端口)只允许使用一次”  这个问题已经不会再出现了。。。