Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 套接字:接收和发送之间的延迟(WriteStream.WriteAsync()和ReadStream.ReadAsync())_C#_Sockets_Xamarin_Xamarin.forms_Exception Handling - Fatal编程技术网

C# 套接字:接收和发送之间的延迟(WriteStream.WriteAsync()和ReadStream.ReadAsync())

C# 套接字:接收和发送之间的延迟(WriteStream.WriteAsync()和ReadStream.ReadAsync()),c#,sockets,xamarin,xamarin.forms,exception-handling,C#,Sockets,Xamarin,Xamarin.forms,Exception Handling,如何正确实现使用WriteStream.WriteAsync()发送字符串和使用ReadStream.ReadAsync()等待响应之间的延迟 我使用rda.SocketsForPCL插件创建TCP客户端套接字,然后创建相应的读写流 当我使用TimeSpan.From毫秒(200))实现延迟时,我得到一个System.NullReferenceException:Object reference未设置为VS 2017中对象的实例。我是C#和Xamarin的新手,我不确定除了上述方法之外如何实现一

如何正确实现使用WriteStream.WriteAsync()发送字符串和使用ReadStream.ReadAsync()等待响应之间的延迟

我使用rda.SocketsForPCL插件创建TCP客户端套接字,然后创建相应的读写流

当我使用TimeSpan.From毫秒(200))实现延迟时,我得到一个System.NullReferenceException:Object reference未设置为VS 2017中对象的实例。我是C#和Xamarin的新手,我不确定除了上述方法之外如何实现一个不会导致抛出异常的延迟

是否有一个“全局”异常处理程序可以以某种方式实现,以处理诸如VS 2017这样的异常,因为VS 2017不会破坏代码,并准确地向您显示异常实际发生的位置

我已经在Xamarin.Forms中实现了下面的活动页面,但它不允许我使用TimeSpan.frommilluses(200))实现延迟在下面的UpdateUserDataAsync()函数中注释:

 public InputPage ()
{
    try
    {
        InitializeComponent();
    }
    catch (Exception ex)
    {
        string err = ex.Message;
        throw;
    }

    client = SharedSocket.Instance().getSocket();                   // Get persistent Socket ===> client connection
    UpdateUserDataAsync();                                          // Used to update the contents of the Listview
    loadSampleData();                                               // Load the Items in the ListView   

    BindingContext = this;

    this.BindingContext = new Relays();                             // Binding the Listview items
    var neg = lstView.BindingContext as Relays;
    InputID = neg.ID;
}

private async void UpdateUserDataAsync()                        // Request and Receive Controller Name
{
    byte[] rv = new byte[] { 0x01, 0x01, 0x01 0x01, 0x01, 0x01, 0x01 };    // Request
    Send_CntrP(rv);                                             // Send request
   //await Task.Delay(TimeSpan.FromMilliseconds(200));
rec2 = await ReceiveByte();
}// UpdateUserDataAsync

private void loadSampleData()
{
    ObservableCollection<Relays> lisInputs = new ObservableCollection<Relays>();

    if (rec2.Length >= 4)
    {
        byte[] states = Encoding.ASCII.GetBytes(rec2);      // Create byte array of received string

        for (int j=6; j<22; j++)
        {
            switch (states[j])
            {
                case 0x00:                                         
                  lisInputs.Add(new Relays { ID = j - 5, Name = "ERROR" + (j - 5), State = "ERROR" });
                    break;

                case 0x01:                                         
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State= "Toggle"});
                     break;

                case 0x02:                                          
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "ON"});
                    break;

                case 0x03:                                          
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "OFF"});
                    break;

                case 0x04:                                          
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "NO"});
                    break;

                case 0x05:                                         
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "NC"});
                    break;

                case 0x10:                                          
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "SC"});
                    break;

                case 0x11:                                         
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "OC"});
                    break;
            }
        }
    }
    else
    {
        for (int i = 0; i < num; i++)
        {
            Images[i] = "round_off.png";
            InputName[i] = "ERROR";
            InputOn[i] = false;
            InputState[i] = "ERROR";

            lisInputs.Add(new Relays { Name = InputName[i] + i, ImageUrl = Images[i], ID = i, State = InputState[i] });
        }
    }

    lstView.ItemsSource = lisInputs;
}

public class MyListItemEventArgs : EventArgs
{
    public Relays MyItem { get; set; }

    public MyListItemEventArgs(Relays item)
    {
        this.MyItem = item;
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++ Sending Messages+++++++++ +++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public async void Send_CntrP(byte[] Comms)
{
    var Len = Comms.Length;                                        // Read the byte array Length

    if (client.Socket.Connected && Len <= 23)                       // No longer than 22 bytes of data to be sent                        
    {
        try
        {
            await client.WriteStream.WriteAsync(Comms, 0, Len);    // Send data of specified Length
            await client.WriteStream.FlushAsync();                           // Make sure all the buffer output data is sent   
            await Task.Delay(TimeSpan.FromMilliseconds(200));      // Delay before next TX to ensure buffer is emptied correctly
        }
        catch (Exception ex)                                       // Exception Handler
        {
            return;
            throw ex;
        }
    }// Client Connected

    else
    {
        XFToast.ShortMessage("Error updating name.\n\rPlease check the connection or length of the entry");   //Android Native Toast Message
    }
}// Send_CntrP 
 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++ Receiving Messages +++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public async Task<string> ReceiveByte()           // Receive messages Asynchronously
{
    int bytesRec = 0;
    var buffer = new byte[28];

    if (client.Socket.Connected)                  // Check Socket connection
    {      
        while (bytesRec != -1)                    // Read received data ---> byte-by-byte
        {
            try
            {
                bytesRec = await client.ReadStream.ReadAsync(buffer, 0, 28);
            }

            catch (Exception ex)                  // Exception Handler (to prevent App crash)
            {
                XFToast.ShortMessage("Error receiving message.\n\rPlease check the WIFI connection.");
                return "ERROR";                   // Return an "ERROR" message if failed
                throw ex;
            }

            var meh = buffer.ToArray();                              
            rec2 = System.Text.Encoding.UTF8.GetString(meh);         

            if (rec2.Length >= 1 && rec2.Length < 30)                
            {
                return await Task.FromResult(rec2);                  // Return a string 
            }
            else
            {
                //await DisplayAlert("Error", "Error receiving message.", "OK");
                XFToast.ShortMessage("Error receiving message.\n\rPlease verify the connection.");   //Android Native Toast Message
                return "ERROR";         // Return an "ERROR" message
            }
        }// Reading response 
    }// Client
    else
    {
        return err;     // Return a "Connection Error" string when no connection is available
    }

    return rec2;         // Return the received bytes in a string 
}// ReceiveByte
// 
  ++++++++++++++++++++++++++++++++++++++++++++++++
 }
公共输入页()
{
尝试
{
初始化组件();
}
捕获(例外情况除外)
{
字符串错误=例如消息;
投
}
client=SharedSocket.Instance().getSocket();//获取持久套接字==>客户端连接
UpdateUserDataAsync();//用于更新Listview的内容
loadSampleData();//加载ListView中的项
BindingContext=这个;
this.BindingContext=new relay();//绑定Listview项
var neg=lstView.BindingContext作为中继;
InputID=neg.ID;
}
私有异步void UpdateUserDataAsync()//请求和接收控制器名称
{
byte[]rv=新字节[]{0x01,0x01,0x01,0x01,0x01,0x01};//请求
Send_CntrP(rv);//发送请求
//等待任务延迟(时间跨度从毫秒(200));
rec2=等待接收字节();
}//UpdateUserDataAsync
私有void loadSampleData()
{
ObservableCollection lisInputs=新的ObservableCollection();
如果(rec2.Length>=4)
{
byte[]states=Encoding.ASCII.GetBytes(rec2);//创建接收字符串的字节数组
对于(int j=6;j=1&&rec2.长度<30)
{
return wait Task.FromResult(rec2);//返回字符串
}
其他的
{
//等待显示警报(“错误”,“接收消息时出错”,“确定”);
XFToast.ShortMessage(“接收消息时出错。\n\r请验证连接。”);//Android本机Toast消息
返回“ERROR”;//返回“ERROR”消息
}
}//阅读反应
}//客户
其他的
{
return err;//当没有可用的连接时,返回“Connection Error”字符串
}
返回rec2;//以字符串形式返回接收到的字节
}//接收字节
// 
++++++++++++++++++++++++++++++++++++++++++++++++
}
我很抱歉写了这么长的文章,但我已经为这个问题挣扎了一段时间,我没有足够的经验处理所有异步方法和异常“查找”,然后处理VS 2017和Xamarin,因为我仍在学习基础知识:(


提前感谢您的帮助/建议。

这是我的解决方案的示例代码

    enum READ_WRITE
    {
        READ,
        WRITE
    }
    public class Test
    {
        private static readonly object readWritelock = new object();
        public static object ReadWrite(READ_WRITE readWrite, object data)
        {
            object returnValue = 0;
            lock (readWritelock)
            {
                switch (readWrite)
                {
                    case READ_WRITE.READ :
                        //add you read code here
                        break;

                    case READ_WRITE.WRITE :
                        //add your write code here
                        break;
                }
            }
            return returnValue;
        }
    }

我通常将读写代码放在同一个锁中,这样一次只能发生一个。然后,你永远不会同时执行读写操作,你总是在读之前等待写操作完成。@jdweng,我如何将它们放在同一个锁(或块)中正如你所提到的?谢谢,我会尝试在我的代码中实现这一点。我仍然无法实现发送和接收之间的延迟;当我发送和调用接收时,它会读取一堆零。这可能是因为它试图读取接收到的消息太快了吗?我对xamarin了解不够,无法给出答案,但我知道Databasee架构非常好。您基本上有一个数据库,问题是该数据库设计用于处理共享事务。共享数据库包含锁定方法,确保您没有冲突。如果您有一个包含10个项目的数据库,而一个客户同时购买9个项目,而另一个客户需要5个项目。2n是什么d客户获取?设计用于共享第二个客户获取1项的数据库。不设计用于共享的数据库为第二个客户提供5项(4项不存在)。