C#客户端到服务器的数据传输服务器正在接收先前的客户端消息“异步服务器-异步客户端”

时间:2018-11-04 22:06:38

标签: c# sockets networking tcp asyncsocket

我正在尝试从客户端向服务器发送消息,并使用c#中的sockets(tcp)显示它。有趣的是服务器正确接收了第一条消息并将其显示,但是当我从客户端向服务器发送第二条消息后,服务器显示客户发送的上一条消息,消息1。

我修改了这个 https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-server-socket-example

还有这个

https://docs.microsoft.com/en-us/dotnet/framework/network-programming/asynchronous-client-socket-example

满足我的需求。

我还录制了一段视频,以更好地说明问题。由于某些原因,服务器程序正在接收客户端发送的先前消息,而不是新发送的消息,这是我程序中发生的事情。

https://www.youtube.com/watch?v=iPjZyzI5A5g&feature=youtu.be

我试图尽量减少我的代码,这会造成更多问题。 谢谢

客户:

using System;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

// This is the code for your desktop app.
// Press Ctrl+F5 (or go to Debug > Start Without Debugging) to run your app.

namespace clientbugaramason
{
    public partial class Form1 : Form
    {
        static Socket client;


        public class StateObject
        {
            public Socket workSocket = null;
            public const int BufferSize = 256;
            public byte[] buffer = new byte[BufferSize];
            public StringBuilder sb = new StringBuilder();
        }
        private static ManualResetEvent connectDone =
           new ManualResetEvent(false);
        private static ManualResetEvent sendDone =
            new ManualResetEvent(false);
        private static ManualResetEvent receiveDone =
            new ManualResetEvent(false);

        public Form1()
        {
            InitializeComponent();
        }
        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                Socket client = (Socket)ar.AsyncState;

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

                connectDone.Set();



            }
            catch (Exception e)
            {
                MessageBox.Show("Cant connect to server.Is it offline ? ");

                connectDone.Set();


            }
        }
        private void Send(String data)
        {
            MessageBox.Show("Data that i am sending to server " + 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 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);
                MessageBox.Show(bytesSent.ToString());

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


        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            // Click on the link below to continue learning how to build a desktop app using WinForms!
            System.Diagnostics.Process.Start("http://aka.ms/dotnet-get-started-desktop");

        }

        private void button1_Click(object sender, EventArgs e)
        {
            Send("message1<EOF>");

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

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

                IPAddress ipAddress = IPAddress.Parse("127.0.0.1");

                IPEndPoint remoteEP = new IPEndPoint(ipAddress, 8080);

                // Create a TCP/IP socket.  
                client = new Socket(ipAddress.AddressFamily,
                   SocketType.Stream, ProtocolType.Tcp);

                // Connect to the remote endpoint.  
                client.BeginConnect(remoteEP,
                    new AsyncCallback(ConnectCallback), client);


                connectDone.WaitOne();
                connectDone.Reset();






            }
            catch (Exception er)
            {
                MessageBox.Show("Cant connecttttt to server.Is it offline ? ");
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Send("message2<EOF>");
        }
    }
}

服务器:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using System.Net;
using System.Net.Sockets;
using System.Threading;

// This is the code for your desktop app.
// Press Ctrl+F5 (or go to Debug > Start Without Debugging) to run your app.

namespace serverbugaramason
{
    public partial class Form1 : Form
    {
        public class Player
        {
            // Client  socket.
            public Socket workSocket = null;
            public string userName = null;
            public bool questionAsked = false;
            public bool questionAnswered = false;
            public int score = 0;
            public string currentAnswer = null;
            // Size of receive buffer.
            public const int BufferSize = 1024;
            // Receive buffer.
            public byte[] buffer = new byte[BufferSize];
            // Received data string.
            public StringBuilder sb = new StringBuilder();
            //Player-Info



            public void SetDefaults()
            {

            }

            public Player()
            {
            }

            public String pIPAddress;
        }


        public Form1()
        {
            InitializeComponent();
        }
        public static ManualResetEvent allDone = new ManualResetEvent(false);

        public void StartListening()
        {

            Console.WriteLine("i am called");
            byte[] bytes = new Byte[1024];


            IPAddress ipAdress = IPAddress.Parse("127.0.0.1");
            IPEndPoint localEndPoint = new IPEndPoint(ipAdress, 8080);

            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listener.Blocking = false;
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(50);


                Console.WriteLine("Server Started, waiting for connections...");
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);


            }
            catch (Exception e)
            {
                MessageBox.Show("Cant start server.");
                Console.WriteLine(e.ToString());
            }

            Console.Read();
        }
        public void AcceptCallback(IAsyncResult ar)
        {

            // Get the socket that handles the client request.
            Socket listener = (Socket)ar.AsyncState;
            Socket clientsocket = listener.EndAccept(ar);
            listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

            // Signal the main thread to continue.
            allDone.Set();
            clientsocket.Blocking = false;      //set to non-blocking
                                                // Create the state object.
            Player PlayerInfo = new Player();
            PlayerInfo.workSocket = clientsocket;

            IPEndPoint thisIpEndPoint = PlayerInfo.workSocket.RemoteEndPoint as IPEndPoint; //Get Local Ip Address
            PlayerInfo.pIPAddress = thisIpEndPoint.Address.ToString();







            clientsocket.BeginReceive(PlayerInfo.buffer, 0, Player.BufferSize, 0, new AsyncCallback(ReadCallback),
                PlayerInfo);

        }
        public void ReadCallback(IAsyncResult ar)
        {

            Player PlayerInfo = (Player)ar.AsyncState;

            Socket clientsocket = PlayerInfo.workSocket;


            try
            {
                String content = String.Empty;


                int bytesRead = clientsocket.EndReceive(ar);

                if (bytesRead > 0)
                {

                    PlayerInfo.sb.Append(Encoding.ASCII.GetString(
                        PlayerInfo.buffer, 0, bytesRead));


                    content = PlayerInfo.sb.ToString();
                    int eofindex = content.IndexOf("<EOF>");
                    if (eofindex > -1)
                    {

                        content = content.Substring(0, eofindex);
                        if (content.Contains("message1"))
                        {
                            MessageBox.Show("Server speaking message1");
                            clientsocket.BeginReceive(PlayerInfo.buffer, 0, Player.BufferSize, 0, new AsyncCallback(ReadCallback),
                PlayerInfo);
                        }
                        if (content.Contains("message2"))
                        {
                            MessageBox.Show("server speaking message2");
                            clientsocket.BeginReceive(PlayerInfo.buffer, 0, Player.BufferSize, 0, new AsyncCallback(ReadCallback),
                PlayerInfo);
                        }



                    }
                    else
                    {
                        clientsocket.BeginReceive(PlayerInfo.buffer, 0, Player.BufferSize, 0, new AsyncCallback(ReadCallback),
                           PlayerInfo);
                    }
                }
                else
                {
                    clientsocket.BeginReceive(PlayerInfo.buffer, 0, Player.BufferSize, 0, new AsyncCallback(ReadCallback),
                              PlayerInfo);
                }
            }
            catch (Exception e)
            {

            }
        }



        private void button1_Click_1(object sender, EventArgs e)
        {
            StartListening();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

是否有可能因为您使用StringBuilder.Append而使您的服务器两次收到相同的消息,然后总是在包含所有接收到的消息的字符串中搜索第一个EOF,并且总是相同?