我正在构建一个通过 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"));
}
}
从 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();
}
我得到的错误是:
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
即使 ip 不同,它也不会执行 tcpclnt.Connect(ip, Port)。 似乎有些东西仍然打开,但我不知道是什么,因为机器已经断开连接。我知道,因为我有 UDP,它会发送它有多少个连接,我可以看到然后增加和减少 OK。
我尝试了“public string Connect_TCP(string ip, int Port)”并在从表单调用连接之前制作了一个新的 dll 实例,但这也不起作用。
感谢到目前为止的回答,但我仍然有问题。我阅读了 MSDN 并制作了一个测试应用程序,现在我可以看到出了什么问题,但目前对如何修复它一无所知。我将 Client 声明为 Static global,因此我可以从连接和断开连接按钮获取它。我认为这总是会创建新实例,而且我从不关闭它们。机器第一次告诉我它已经断开连接,但应用程序永远不会重新连接在 Debug模式下,它在 client.Connect(ipEndPoint) 处失败; “InvalidOperationException was unhandled”后跟“一旦套接字断开连接,您只能异步重新连接,并且只能重新连接到不同的端点。必须在操作完成之前不会退出的线程上调用 BeginConnect。”
我想我需要将这个 Client 放在 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");
}
}
}
最佳答案
一旦断开 TCP 套接字,就无法重新连接。您必须释放套接字并创建一个新套接字。这不仅限于 .NET TCPClient 类,这是所有套接字 API(WinSock、BSD 等)的一般工作方式。
此规则的异常(exception)是 WinSock2 特定的 DisconnectEx() 函数,它有一个 TF_REUSE_SOCKET 标志,允许 ConnectEx() (和 AcceptEx()) 重新使用现有的 SOCKET 而不是需要创建新的套接字。但这不适用于您的情况。
在大多数情况下,一旦断开套接字,就必须从头开始创建一个新套接字。
关于sockets - TCPClient 只会连接一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25908270/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里
require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame
-if!request.path_info.include?'A'%{:id=>'A'}"Text"-else"Text"“文本”写了两次。我怎样才能只写一次并同时检查path_info是否包含“A”? 最佳答案 有两种方法可以做到这一点。使用部分,或使用content_forblock:如果“文本”较长,或者是一个重要的子树,您可以将其提取到一个部分。这会使您的代码变干一点。在给出的示例中,这似乎有点矫枉过正。在这种情况下更好的方法是使用content_forblock,如下所示:-if!request.path_info.inc
考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d