TCPClient只能连接一次

use*_*423 2 sockets tcp tcpclient

我正在构建一个通过TCP与机器通信的应用程序.我遇到的问题是我可以连接并且一切都很好但是一旦我断开连接然后尝试重新连接所有我得到的是错误

我在表单中的代码是

   private void btn_connect_Click(object sender, EventArgs e)
    {
        try
        {

            Log(LogMsgType.Normal, String.Format("Connected on {0}\n", DateTime.Now));

            string ip = (txt_ipadd_1.Text + "." + txt_ipadd_2.Text + "." + txt_ipadd_3.Text + "." + txt_ipadd_4.Text);

            Log(LogMsgType.Normal, String.Format("Connecting to IP address " + ip + "   Port # " + txt_port.Text +"\n"));

            string con = Codenet.Connect_TCP(ip, Convert.ToInt32(txt_port.Text)); //connect to this one

            Log(LogMsgType.Normal, String.Format(con + "\n"));

            toolStripStatusLabel1.Text = "Connected";

            btn_connect.Visible = false;
            btn_disconnect.Visible = true;
            ip = "";


        }

        catch (Exception d)
        {
            Log(LogMsgType.Error, String.Format("Error..... " + d.StackTrace +"\n"));
        }
    }
Run Code Online (Sandbox Code Playgroud)

这将转到Codenet dll中的代码,该代码执行连接和断开连接

     public static string Connect_TCP(string ip, int Port)
    {
            tcpclnt.Connect(ip, Port); 
            connection_type = "TCP";
            return "Connected OK ";
    }

    public static void DisConnect_TCP()
    {
        tcpclnt.GetStream().Close();   
        tcpclnt.Close();
    }
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

Error..... at System.Net.Sockets.TcpClient.Connect(String hostname, Int32 port) at
comms_engine.Codenet.Connect_TCP(String ip, Int32 Port) in C:\a\code\g_com_test_1\comms_engine\Codenet.cs:line 37 at
comms_test.CommTester.btn_connect_Click(Object sender, EventArgs e) in C:\a\code\g_com_test_1\dll_test\ethernet.cs:line 98
Run Code Online (Sandbox Code Playgroud)

即使ip不同,它也不会执行tcpclnt.Connect(ip,Port).似乎某些东西仍然是开放的,但我不知道机器已断开连接.我知道,因为我有UDP,它发送了它有多少连接,我可以看到然后增加和减少OK.

我尝试了"公共字符串Connect_TCP(字符串IP,int端口)"并创建一个新的dll实例,从表单调用连接,但这也不起作用.

我有什么不妥的想法.

到目前为止,感谢您的答案,但我仍然有一个问题.我阅读了MSDN并制作了一个测试应用程序,我现在可以看到出了什么问题,但我现在对如何修复它一无所知.我将Client声明为Static global,因此我可以通过connect和disconnect按钮获取它.我认为这总是创造新的实例,我永远不会关闭它们.第一次机器告诉我它已经连接到应用程序永远不会重新连接在调试模式下它会在客户端崩溃.连接(ipEndPoint); "InvalidOperationException未处理"后跟"一旦套接字断开连接,您只能异步重新连接,并且只能重新连接到另一个EndPoint.必须在一个线程上调用BeginConnect,该线程在操作完成之前不会退出."

我想我需要把这个客户端放在btn_connect_click中并从断开连接中获取指向它的指针,但是如何?

完整的代码是

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.IO;
using System.IO.Ports;
using System.Diagnostics;
using System.Threading;

namespace TCP_Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        static  Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        private void btn_connect_Click(object sender, EventArgs e)
        {

            string ip = (txt_ipadd_1.Text + "." + txt_ipadd_2.Text + "." + txt_ipadd_3.Text + "." + txt_ipadd_4.Text);

            IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress ipAddr = IPAddress.Parse(ip);
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, Convert.ToInt32(txt_port.Text));

            // Connect the socket to the remote end point.
            client.Connect(ipEndPoint);

            rchTxtBx_output.AppendText("connected to " + ipEndPoint + "\n\r");
          }

          private void btn_disconnect_Click(object sender, EventArgs e)
          {
            client.Shutdown(SocketShutdown.Both);

            client.Disconnect(true);
            if (client.Connected)
                rchTxtBx_output.AppendText("We're still connnected \n\r");
            else
                rchTxtBx_output.AppendText("We're disconnected \n\r");

           }




    }


} 
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 5

一旦断开 TCP 套接字,就无法重新连接。您必须释放套接字并创建一个新套接字。这不仅限于 .NETTCPClient类,这也是所有套接字 API(WinSock、BSD 等)的一般工作方式。

此规则的例外是 WinSock2 特定DisconnectEx()函数,它有一个TF_REUSE_SOCKET标志允许ConnectEx()(和AcceptEx())重用现有套接字SOCKET,而不需要创建新套接字。但这不适用于您的情况。

在大多数情况下,一旦断开套接字,就必须从头开始创建一个新套接字。


use*_*423 5

谢谢你的帮助我现在解决了它.请参阅上面的完整代码,但下面是使其工作的teh片段.只需添加client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 在连接按钮内.我的测试现在显示它连接和断开连接,并允许重新连接或连接到其他机器.只有我两个人的日子才能在你的帮助下完成工作.

static  Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);



    private void btn_connect_Click(object sender, EventArgs e)
    {
        if (client.Connected)
        {
            client.Shutdown(SocketShutdown.Both);

            client.Disconnect(true);
            client.Close();
        }
        else
        {
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                string ip = (txt_ipadd_1.Text + "." + txt_ipadd_2.Text + "." + txt_ipadd_3.Text + "." + txt_ipadd_4.Text);

                IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
Run Code Online (Sandbox Code Playgroud)