【问题标题】:send and receive in socket [closed]在套接字中发送和接收 [关闭]
【发布时间】:2014-07-21 15:12:44
【问题描述】:

我在c#中通过socket发送对象时遇到问题,我的客户端可以发送到服务器但服务器不能发送到客户端,我认为客户端有问题。

服务器

    private void Form1_Load(object sender, EventArgs e)
    {
        CheckForIllegalCrossThreadCalls = false;
        Thread a = new Thread(connect);
        a.Start();
    }

    private void sendButton_Click(object sender, EventArgs e)
    {
        client.Send(SerializeData(ShapeList[ShapeList.Count - 1]));
    }

    void connect()
    {
        try
        {               
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555);
            server.Bind(iep);
            server.Listen(10);
            client = server.Accept();
            while (true)
            {
                byte[] data = new byte[1024];
                client.Receive(data);
                PaintObject a = (PaintObject)DeserializeData(data);
                ShapeList.Add(a);
                Invalidate();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

客户

private void Form1_Load(object sender, EventArgs e)
    {
        CheckForIllegalCrossThreadCalls = false;
        Thread a = new Thread(connect);
        a.Start();
    }

    private void SendButton_Click(object sender, EventArgs e)
    {
        client.Send(SerializeData(ShapeList[ShapeList.Count - 1]));
    }

    void connect()
    {
        try
        {            
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555);
            client.Connect(iep);
            while (true)
            {
                byte[] data = new byte[1024];
                client.Receive(data);
                PaintObject a = (PaintObject)DeserializeData(data);
                ShapeList.Add(a);
                Invalidate();
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

【问题讨论】:

  • 什么是“服务器无法发送到客户端”?发生什么了?另请参阅Why does my client socket not receive what my server socket sends?
  • 是的,我的项目是画一个像线一样的形状,然后通过套接字发送,客户端可以将形状发送到服务器,但我不能将形状从服务器发送到客户端,我也看了你的链接,但我不太明白,你能更清楚地告诉我吗?
  • “无法将形状从服务器发送到客户端”是什么意思?发生什么了?你有例外吗?我提供的链接提到您的client.Receive(data); 不一定会收到您的服务器发送的所有数据。

标签: c# sockets send


【解决方案1】:
CheckForIllegalCrossThreadCalls = false;

删除它并修复弹出的错误。如果你压制错误,修复它们就更难了。

【讨论】:

    【解决方案2】:
    client = server.Accept();
    

    在一个线程中:

    client.Send(SerializeData(ShapeList[ShapeList.Count - 1]));
    

    在 UI 线程中。

    这不是线程安全的。

    您的客户端循环接收数据,您希望何时发送?我建议在点击 (http://msdn.microsoft.com/en-us/library/dd267265(v=vs.110).aspx) 中添加线程安全队列,并在合适的时候在循环中发送:

    while (true)
    {
        byte[] data = new byte[1024];
        var received = client.Receive(data);
        if(received > 0)
        { //careful, how do you know you have it all?
          PaintObject a = (PaintObject)DeserializeData(data);
          ShapeList.Add(a);
          Invalidate();
        }
        if(!queue.IsEmpty)
        {
           //queue dequeue and send
           client.Send(...);
        }
    }
    

    更完整的例子

    //threadsafe queue
    private readonly ConcurrentQueue<byte[]> queue = new ConcurrentQueue<byte[]>();
    
    private void SendButton_Click(object sender, EventArgs e)
    {
        //queue it up
        queue.Enqueue(SerializeData(ShapeList[ShapeList.Count - 1]));
    }
    
    void connect()
    {
        try
        {            
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 5555);
            client.Connect(iep);
            while (true)
            {
                byte[] data = new byte[1024];
                var received = client.Receive(data);
                if(received > 0)
                { //careful, how do you know you have it all?
                  PaintObject a = (PaintObject)DeserializeData(data);
                  ShapeList.Add(a);
                  Invalidate();
                }
                while(!queue.IsEmpty)
                {
                   //queue dequeue and send
                   client.Send(queue.Dequeue());
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    

    【讨论】:

    • 我不太明白,我是 c# 的新手,我该如何解决这个问题?你能更清楚地告诉我吗?
    • 你去吧,它不能保证工作。就我个人而言,我现在避免像插座一样低水平。但它肯定是线程安全的。
    • @user3696492 如果你是 C# 新手,我也会同意 weston,而不是使用套接字,而是使用更高的抽象层,例如 WCF 或其他一些通信库。
    • 好的,非常感谢你们,我会努力的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-21
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多