解决 套接字编程

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
你好
我目前正在使用套接字编程将命令发送到设备,然后它发送回复命令。
如何获得控制台以读取返回的回复?

到目前为止,我有

C#:
 m_socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                System.Net.IPAddress remoteIPAddress = System.Net.IPAddress.Parse(DatalogicIP);
                System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, DatalogicPort);
                m_socClient.Connect(remoteEndPoint);
                Console.WriteLine("Connection Successful");
                Console.ReadLine();

能够成功连接,然后即时发送

C#:
string hostMode = "<ESC>[C";
C#:
 byte[] byData = System.Text.Encoding.ASCII.GetBytes(hostMode);
                m_socClient.Send(byData);

我应该收到<ESC> H <CR><LF>返回,但我如何让控制台进行聆听并显示回复
一旦我拿回了H,我希望以后可以发送另一个命令

感谢任何帮助(是套接字的新手)

谢谢
汤姆
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
嘿,
我以Windows为例。
这是我的密码
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace SVS_Console
{
    // State object for receiving data from remote device. 
    public class StateObject
    {
        // Client socket. 
        public Socket workSocket = null;
        // Size of receive buffer. 
        public const int BufferSize = 256;
        // Receive buffer. 
        public byte[] buffer = new byte[BufferSize];
        // Received data string. 
        public StringBuilder sb = new StringBuilder();
    }

    public class AsynchronousClient
    {
        // The port number for the remote device. 
        private const int port = 1023;

        // ManualResetEvent instances signal completion. 
        private static ManualResetEvent connectDone =
            new ManualResetEvent(false);
        private static ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);

        // The response from the remote device. 
        private static String response = String.Empty;

        private static void StartClient()
        {
            // Connect to a remote device. 
            try
            {
                // Establish the remote endpoint for the socket. 
                // The name of the   
                // remote device is "host.contoso.com". 
                IPHostEntry ipHostInfo = Dns.GetHostEntry("192.168.4.15");
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

                // Create a TCP/IP socket. 
                Socket client = new Socket(ipAddress.AddressFamily,
                    SocketType.Stream, ProtocolType.Tcp);
                Console.WriteLine("Connecting to Datalogic device " + ipAddress + "");
                // Connect to the remote endpoint. 
                client.BeginConnect(remoteEP,
                    new AsyncCallback(ConnectCallback), client);
                connectDone.WaitOne();

                Console.WriteLine("Press To Send Command For Host Mode Programming To The System");
                Console.ReadLine();
                // Send test data to the remote device. 
                Send(client, "\0C\r\n");
                sendDone.WaitOne();
                Console.WriteLine("Press to receive");
                //从远程设备接收响应。 
                接收(客户);
                receiveDone.WaitOne();

                //将响应写入控制台。 
                Console.WriteLine("收到回复:{0}", response);


                Console.ReadLine();
                Console.WriteLine("Did you read Response?");


                // Release the socket. 
               // client.Shutdown(SocketShutdown.Both);
              //  client.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object. 
                Socket client = (Socket)ar.AsyncState;

                // Complete the connection. 
                client.EndConnect(ar);

                Console.WriteLine("Socket connected to {0}",
                    client.RemoteEndPoint.ToString());

                // Signal that the connection has been made. 
                connectDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void Receive(Socket client)
        {
            try
            {
                // Create the state object. 
                StateObject state = new StateObject();
                state.workSocket = client;

                // Begin receiving the data from the remote device. 
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the state object and the client socket   
                // from the asynchronous state object. 
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device. 
                int bytesRead = client.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There might be more data, so store the data received so far. 
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                    // Get the rest of the data. 
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    // All the data has arrived; put it in response. 
                    if (state.sb.Length > 1)
                    {
                        response = state.sb.ToString();
                    }
                    // Signal that all bytes have been received. 
                    receiveDone.Set();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void Send(Socket client, String data)
        {
            // Convert the string data to byte data using ASCII encoding. 
            byte[] byteData = Encoding.ASCII.GetBytes(data);

            // Begin sending the data to the remote device. 
            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }

        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                // Retrieve the socket from the state object. 
                Socket client = (Socket)ar.AsyncState;

                // Complete sending the data to the remote device. 
                int bytesSent = client.EndSend(ar);
                Console.WriteLine("Sent {0} bytes to server.", bytesSent);

                // Signal that all bytes have been sent. 
                sendDone.Set();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        public static int Main(String[] args)
        {
            StartClient();
            return 0;
        }
    }
}

收到来自远程设备的响应后,我已放置了ConsoleReadLine。
C#:
接收(客户);
receiveDone.WaitOne();
                //将响应写入控制台。 
                Console.WriteLine("收到回复:{0}", response);

当我在大力神中回复时,什么也没有回来。我将其寄回进行测试(下)

1583765585270.png


基本上,一旦我发送<ESC>我会收到回信<ESC>H<CR><LF>。收到我需要检查的信息后,再发送另一个命令<ESC>B,然后我收到一个<ESC>S<CR><LF>背部。一旦有了,我就发送另一个命令,然后我需要读取之后返回的字符串,并在可能的情况下对它们进行计数。

干杯
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
Did you set a breakpoint on ReceiveCallback()? Is it even being called?
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
插入的断点及其行为相同。我想这部分会从接收回叫接收


sendDone.WaitOne();
Console.WriteLine("Press to receive");
//从远程设备接收响应。
接收(客户);
receiveDone.WaitOne();
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
启用但未命中(执行任何操作)时,Breakpoijt变成红色圆圈。要检查我是否处于调试模式并检查调试设置。该福彩12选5走势图看起来不错,所以我不能srr为什么它没有显示结果...啊。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
当您将红点放在要插入福彩12选5走势图的任意行上时,这只是一个断点,一旦到达该福彩12选5走势图,程序将暂停,调试器将以黄色箭头指示;指示任何调用福彩12选5走势图调用的行均已到达该行。然后,在此步骤中,您需要按F11键以完成福彩12选5走势图!我的签名中有一个调试教程,您可以从中受益。

此示例屏幕截图显示了放置但未到达的断点。

Screenshot_83.jpg


此示例屏幕截图显示了已放置并达到了断点。

截图_84.jpg
 
Last edited:

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
对不起,我很愚蠢。
我看不到它没有得到我的回复

如果我注释掉下面的福彩12选5走势图,显然不会得到答复。如果它在程序中,则它正在等待答复,但未取回答复。
我在Microsoft上再次浏览了该程序,看不到任何明显的区别...

C#:
 //从远程设备接收响应。 
                接收(客户);
                receiveDone.WaitOne();



                //将响应写入控制台。 
                Console.WriteLine("收到回复:{0}", response);



//将响应写入控制台。
Console.WriteLine("收到回复:{0}", response);


这部分一定有问题...但是我不知道是什么

C#:
 private static void Receive(Socket client)
        {
            try
            {
                // Create the state object. 
                StateObject state = new StateObject();
                state.workSocket = client;

                // Begin receiving the data from the remote device. 
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private static void ReceiveCallback(IAsyncResult ar)
        
        {
            try
            {
              
                // Retrieve the state object and the client socket   
                // from the asynchronous state object. 
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.workSocket;

                // Read data from the remote device. 
                int bytesRead = client.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There might be more data, so store the data received so far. 
                    state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                    // Get the rest of the data. 
                    client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), state);
                }
                else
                {
                    // All the data has arrived; put it in response. 
                    if (state.sb.Length > 1)
                    {
                        response = state.sb.ToString();
                    }
                    // Signal that all bytes have been received. 
                    receiveDone.Set();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
我没有在我的签名中链接此文件来获得乐趣: 使用调试器浏览福彩12选5走势图-Visual Studio 然后告诉您阅读它,以便可以确定项目中正在发生的事情。

注意:

C#:
.WaitOne();

根据文档:
等待一个()阻塞当前线程,直到当前线程 WaitHandle 接收信号。
WaitHandle.WaitOne方法(System.Threading) -如果取消该行有帮助,则意味着可能有某些情况阻止了您的调用福彩12选5走势图。只有通过调试,您才能找到那是什么。没有人,但是您可以为您做。

还有一点是,您不应该使用硬编码的假布尔值来编写手动重置事件,而是建议您使用Get; 组ters;。代替。 :
C#:
private static ManualResetEvent receiveDone = new ManualResetEvent(false);

尽管Microsoft自己实际上按照您提供的方式提供了文档,但并非我建议的那样,否则也可能会给您带来一些问题。 ManualResetEvent的想法是,您可以控制何时以及如何调用reset事件。另请注意,文档还说以下内容:
按下 输入 再次导致该示例调用 重启 方法并启动另一个线程,该线程在调用时阻塞 等待一个。按下 输入 关键一次最后一次通话 释放最后一个线程,程序结束。

请参阅有关该报价的文档: ManualResetEvent类(System.Threading)

最后,阅读我链接的调试链接,然后开始进入您的福彩12选5走势图,检查当前执行的所有内容。注意;如果您的任何调用福彩12选5走势图被告知要继续轮询其他方法 当一个人执行,您还需要在其他方法上设置一个断点,以便调试器也可以在它们触发时捕获...在您提供的示例中我还可以看到其他问题,但是我只能给您很多建议,如果您实际调试福彩12选5走势图,所有这些对您来说都是显而易见的。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
但是第33行是一个断点。您是否正在接收数据?
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
关于重置事件的另一件事: 5分钟的ManualResetEvent指南 -请阅读有关我在第29条上发表的评论的内容。尽管此处可能还有其他一些开发人员不同意不遵循默认文档,但在阅读该文章时应该会清楚。关于这个为什么我做的有些不同,我将在下面简要解释:
在上面的福彩12选5走势图中,我们使用false值初始化ManualResetEvent,这意味着所有调用WaitOne方法的线程都将阻塞,直到某些线程调用Set()方法为止。

如果我们使用true值初始化ManualResetEvent,则所有调用WaitOne方法的线程都不会阻塞并且可以继续进行下去。
当我不编写测试/开发福彩12选5走势图时,我习惯于使用: INotifyPropertyChanged接口(System.ComponentModel) 如果我的方法正在轮询,则可以调用将ManualResetEvent的布尔值的setter更新为true,然后让属性更改的接口负责启动重置过程,并可以确保.set()为要求财产变真实;因此,调用reset事件将释放该线程用于下一个轮询调用。

我不建议您一分钟后调用set()来释放线程。您最好先确定是什么导致线程被扣为人质,并首先从调用福彩12选5走势图中确定阻塞的根源。

我希望您发现此信息有用,更重要的是,您了解我建议您做的事情。
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
嗨道林斯,谢谢您抽出宝贵的时间帮助我。现在,我将遍历dubug,看看我是否可以识别问题并通过其余的评论。我将发布我的进展情况。干杯的人
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
因此,同步当然是我想要做的最好的事情。
设法让它发送字符串,读取字符串。
现在正在为HEX构建HEX命令<ESC> <CR> <LF>
 

tdignan87

知名会员
已加入
2019年7月8日
留言内容
95
编程经验
Beginner
例如,我需要以十六进制发送数据。
我需要发送1b5b43(<ESC>[C)我将字符串转换为字节,但在大力神上仅显示为字面上的1b5b43。有人帮忙吗?

C#:
 // string input = @"<ESC>[C";
            string input = @"1b5b43";
            byte[] encode = Encoding.UTF8.GetBytes(input);
            string result = ConnectServerAndGetResultByInput(input);
            if (string.Compare(@"<ESC>H<CR><LF>", result, true) == 0)
            {
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
A lot of your problems seems to stem from a lack of understanding of characters, strings, and encodings. 1b 4b 53 are already the hex values of the bytes you want to send.

由于某种原因,您做了一个琴弦"1b4b53", and asked the framework to get the bytes representing that string. That would result in the hex bytes 31 62 34 62 35 33. It is these bytes that you ended up sending, and so the terminal obviously converted those bytes back to ASCII.

我建议再次检查ASCII表,例如 @谢平 告诉你上次学习
 
Last edited:

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,500
地点
弗吉尼亚州切萨皮克
编程经验
10+
@谢平 实际上是在指引您正确的道路。也许您只是需要听到用不同方式表达的同一件事。既然他是我的好虚拟双胞胎,并且告诉您在学习过程中以及与学习学生有关的方面您需要什么,我倾向于成为邪恶的双胞胎,他们会嘴和/或讽刺,只是将信息泵入消防水带。

与我的相比,大多数人对他的风格反应更好。关于蝇,蜂蜜和醋的东西。 😜 有时候,尽管我的风格提出了适量的挑战,但要让学生走下去"我比那聪明。我将展示那个疯狂的跳伞运动员。"就个人而言,我宁愿成为Sheepings班的学生。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
也许您只是需要听到用不同方式表达的同一件事。
或者,也许他们只是不注意自己的主题以及给出的指示。
就个人而言,我宁愿成为Sheepings班的学生。
你说的很好 @跳伞。我不太擅长回复关于我自己的帖子,大声笑,谢谢。 🙏

我知道这是我要在后面说些好话的地方,但是您知道我对消防水带方法的表现力和发布福彩12选5走势图示例时总是遇到问题。所以当你说:
我倾向于成为邪恶的双胞胎,他们会狡猾和/或讽刺,只会将信息注入消防水带。
这是我们在帮助论坛上展示信息时的不同之处。我是否为自己编写了几乎所有自己的福彩12选5走势图,并将所有相关联的内容(主要是与Linq和Lambda表达式结合在一起),这使得新手和初学者几乎不可能阅读,理解和查找使用Lambda表达式的方法中构想的内联变量。这就是为什么几乎所有我的福彩12选5走势图示例都是显式编写的,而没有诸如Linq joinder之类的东西的原因-通常像Microsoft文档那样使用示例。

我在论坛上为用户编写福彩12选5走势图的方式以及我如何回答问题的方式比您使用消防水带方式的方式更具表达力,消防水带方式通常将答案抛在最前面,但为用户提供了更多的研究机会。

我们在福彩12选5走势图示例如何经常无法解释以及大多数情况下没有内联或外部注释的方式上也有所不同。因此,当您比较我们的教学方式时,我考虑了我的起步方式以及发现的更多帮助。我总是发现,向我解释一个场景或福彩12选5走势图块的细节更加详尽,比收到带有我不理解它是如何工作或如何做的福彩12选5走势图块的福彩12选5走势图转储要有用得多。

这常常使我对收到的福彩12选5走势图提出更多的问题,从而使您在真正想了解更多有关所获得的知识时,看起来像是帮助吸血鬼。因此,当我帮助董事会成员时,我会考虑许多月前开始时的感受。以及我发现哪种答案更有用。而且,我也想参加我的课程!大声笑没有罪行。

无论如何,尽管已解决,但还是不要回避:
感谢你的帮助。现在没关系,通过阅读跳伞者的评论,我意识到我要去哪里错了。感激

我仍然不确定与我所说的完全不同的是,Skydiver会更清楚地说明吗?无论如何,您如何解决此问题?如果您确实解决了问题,原因是什么?

@ tdignan87 -请记住,我个人的工作量非常大,并且我在论坛上的几乎所有回复都努力做到尽职尽责。由于时间限制,这通常很难做到。但是,我在这里为您提供帮助。因此,如果您发现我的答复之一并不能完全解释或回答您的主题。告诉我,我将尝试阐明我以前的答复,以使您对我给您的指示有更好的了解。
 
最佳 底部