C# 为什么可以';我不能在套接字连接上发送两次数据吗?

C# 为什么可以';我不能在套接字连接上发送两次数据吗?,c#,sockets,asynchronous,C#,Sockets,Asynchronous,我正在编写一个简单的客户机-服务器套接字程序,无法理解为什么我的客户机只在第一次按下“发送”按钮时发送 第二次调用“nwStream.Write(bytesToSend,0,bytesToSend.Length);”时,服务器不会获取数据 注意:我已经注释掉了从服务器到客户端的回显,因为服务器在回显之后正在关闭连接。我希望连接保持打开状态 请帮我发送数据两次 这是C#表单客户端代码 public partial class Form1 : Form { public Form1()

我正在编写一个简单的客户机-服务器套接字程序,无法理解为什么我的客户机只在第一次按下“发送”按钮时发送

第二次调用“nwStream.Write(bytesToSend,0,bytesToSend.Length);”时,服务器不会获取数据

注意:我已经注释掉了从服务器到客户端的回显,因为服务器在回显之后正在关闭连接。我希望连接保持打开状态

请帮我发送数据两次

这是C#表单客户端代码

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    TcpClient client;
    private void Form1_Load(object sender, EventArgs e)
    {
        textBox_IP.Text = "192.168.0.72";
    }

    const int PORT_NO = 11000;
    private void button_Start_Click(object sender, EventArgs e)
    {
        client = new TcpClient(textBox_IP.Text, PORT_NO);
        textBox_MsgToSend.Text = "Started";
    }

    private void button_Send_Click(object sender, EventArgs e)
    {
        string textToSend = textBox_MsgToSend.Text + " " + DateTime.Now.ToString();
        textToSend += "<EOF>";

        NetworkStream nwStream = client.GetStream();
        byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(textToSend);

        //---send the text---
        textBox_Sending.Text = textToSend;
        textBox_Size.Text = bytesToSend.Length.ToString();
        nwStream.Write(bytesToSend, 0, bytesToSend.Length);

       // commented out as the server does not echo anything back
       //---read back the text---
       //            byte[] bytesToRead = new byte[client.ReceiveBufferSize];
       //            int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
       //            textBox_Received.Text = bytesRead.ToString();
    }

    private void button_Close_Click(object sender, EventArgs e)
    {
        client.Close();
        textBox_MsgToSend.Text = "Closed";
    }

}
以下是服务器代码:

public class AsynchronousSocketListener
{
    // Thread signal.
    public static ManualResetEvent allDone = new ManualResetEvent(false);

    public AsynchronousSocketListener()
    {
    }

    public static void StartListening(string ip)
    {
        // Data buffer for incoming data.
        byte[] bytes = new Byte[1024];

        IPAddress address = IPAddress.Parse(ip);

        Console.WriteLine("listening on IP " + ip + " Port " + "11000");

        IPEndPoint localEndPoint = new IPEndPoint(address, 11000);

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

        // Bind the socket to the local endpoint and listen for incoming connections.
        try
        {
            listener.Bind(localEndPoint);
            listener.Listen(100);

            while (true)
            {
                // Set the event to nonsignaled state.
                allDone.Reset();

                // Start an asynchronous socket to listen for connections.
                Console.WriteLine("Waiting for a connection...");
                listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);

                // Wait until a connection is made before continuing.
                allDone.WaitOne();
            }

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

        Console.WriteLine("\nPress ENTER to continue...");
        Console.Read();

    }

    public static void AcceptCallback(IAsyncResult ar)
    {
        // Signal the main thread to continue.
        allDone.Set();

        // Get the socket that handles the client request.
        Socket listener = (Socket)ar.AsyncState;
        Socket handler = listener.EndAccept(ar);

        Console.WriteLine("Connected...");

        // Create the state object.
        StateObject state = new StateObject();
        state.workSocket = handler;
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
    }

    public static void ReadCallback(IAsyncResult ar)
    {
        Console.WriteLine("ReadCallback");

        string content = string.Empty;

        // Retrieve the state object and the handler socket
        // from the asynchronous state object.
        StateObject state = (StateObject)ar.AsyncState;
        Socket handler = state.workSocket;

        // Read data from the client socket. 
        int bytesRead = handler.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));

            // Check for end-of-file tag. If it is not there, read 
            // more data.
            content = state.sb.ToString();
            if (content.IndexOf("<EOF>") > -1)
            {
                // All the data has been read from the 
                // client. Display it on the console.
                Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);

                // I commented this out as when the send completes, the server closes the connection... I want the connection to remain open
                // Echo the data back to the client.
                //Send(handler, content);
            }
            else
            {
                // Not all data received. Get more.
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
            new AsyncCallback(ReadCallback), state);
            }
        }
    }

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

        Console.WriteLine("Echo back to client : " + data);

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

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

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

            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }
尝试1:

我在公共静态void AcceptCallback(IAsyncResult ar)函数中尝试了这一点:

    while(true)
    {
        handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
    }
尝试2:

根据SpaceghostAli的回复/代码:不起作用。。。第二次发送时崩溃

public static void ReadCallback(IAsyncResult ar)
{
    string content = string.Empty;

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar);

    if (bytesRead > 0)
    {
        Console.WriteLine("ReadCallback");

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

        // Check for end-of-file tag. If it is not there, read 
        // more data.
        content = state.sb.ToString();
        if (content.IndexOf("<EOF>") > -1)
        {
            // All the data has been read from the 
            // client. Display it on the console.
            Console.WriteLine("Read {0} bytes from socket. Data : {1}", content.Length, content);

            state = new StateObject();
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

            // Echo the data back to the client.
            //                Send(handler, content);
        }
        else
        {
            // Not all data received. Get more.
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }
    }
}
publicstaticvoidreadcallback(IAsyncResult ar)
{
string content=string.Empty;
//检索状态对象和处理程序套接字
//从异步状态对象。
StateObject状态=(StateObject)ar.AsyncState;
套接字处理程序=state.workSocket;
//从客户端套接字读取数据。
int bytesRead=handler.EndReceive(ar);
如果(字节读取>0)
{
Console.WriteLine(“ReadCallback”);
//可能会有更多数据,因此请存储到目前为止收到的数据。
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
//检查文件结尾标记。如果不存在,请读取
//更多数据。
content=state.sb.ToString();
if(content.IndexOf(“”>-1)
{
//所有数据都已从数据库中读取
//客户端。在控制台上显示它。
WriteLine(“从套接字读取{0}字节。数据:{1}”,content.Length,content);
state=新的StateObject();
BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReadCallback),state);
//将数据回显到客户端。
//发送(处理程序、内容);
}
其他的
{
//未收到所有数据。获取更多信息。
BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReadCallback),state);
}
}
}
尝试3:

根据David所说的进行另一次尝试,但在函数末尾重置BeginReceive-有效

public static void ReadCallback(IAsyncResult ar)
{
    string content = string.Empty;

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar);

    if (bytesRead > 0)
    {
        Console.WriteLine("ReadCallback");

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

        // Check for end-of-file tag. If it is not there, read 
        // more data.
        content = state.sb.ToString();
        if (content.IndexOf("<EOF>") > -1)
        {
            // All the data has been read from the 
            // client. Display it on the console.
            Console.WriteLine("Read {0} bytes from socket. Data : {1}", content.Length, content);

            // Echo the data back to the client.
            Send(handler, content);
        }
        else
        {
            // Not all data received. Get more.
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }
    }

    // clear the state object's buffer and queue the next begin receive
    state.sb.Clear();
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
publicstaticvoidreadcallback(IAsyncResult ar)
{
string content=string.Empty;
//检索状态对象和处理程序套接字
//从异步状态对象。
StateObject状态=(StateObject)ar.AsyncState;
套接字处理程序=state.workSocket;
//从客户端套接字读取数据。
int bytesRead=handler.EndReceive(ar);
如果(字节读取>0)
{
Console.WriteLine(“ReadCallback”);
//可能会有更多数据,因此请存储到目前为止收到的数据。
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
//检查文件结尾标记。如果不存在,请读取
//更多数据。
content=state.sb.ToString();
if(content.IndexOf(“”>-1)
{
//所有数据都已从数据库中读取
//客户端。在控制台上显示它。
WriteLine(“从套接字读取{0}字节。数据:{1}”,content.Length,content);
//将数据回显到客户端。
发送(处理程序、内容);
}
其他的
{
//未收到所有数据。获取更多信息。
BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReadCallback),state);
}
}
//清除状态对象的缓冲区,并将下一次开始接收排队
把某人说清楚;
BeginReceive(state.buffer,0,StateObject.BufferSize,0,新异步回调(ReadCallback),state);
}

一旦服务器读取消息并将其写入控制台,它就再也不会开始读取了。它只是退出“ReadCallback”。服务器的连接保持打开状态,但它将不再读取


要解决此问题,您可能应该在写出上次收到的消息后启动另一个“BeginReceive”。

一旦您的服务器读取消息并将其写入控制台,它就再也不会开始读取了。它只是退出“ReadCallback”。服务器的连接保持打开状态,但它将不再读取


要解决这个问题,您可能应该在写下最后一条收到的消息后再开始一次“BeginReceive”。

我对David的答案投了赞成票,因为我认为它是正确的,所以请将其标记为正确的,这只是为了根据您的更新澄清他的意思

public static void ReadCallback(IAsyncResult ar)
{
    Console.WriteLine("ReadCallback");

    string content = string.Empty;

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    // Read data from the client socket. 
    int bytesRead = handler.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));

        // Check for end-of-file tag. If it is not there, read 
        // more data.
        content = state.sb.ToString();
        if (content.IndexOf("<EOF>") > -1)
        {
            // All the data has been read from the 
            // client. Display it on the console.
            Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);

            // continue reading
            state = new StateObject();
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);

            // I commented this out as when the send completes, the server closes the connection... I want the connection to remain open
            // Echo the data back to the client.
            //Send(handler, content);
        }
        else
        {
            // Not all data received. Get more
            // start writing at bytesRead in the buffer so you don't lose the partially read data
            handler.BeginReceive(state.buffer, bytesRead, StateObject.BufferSize, 0,
        new AsyncCallback(ReadCallback), state);
        }
    }
}
publicstaticvoidreadcallback(IAsyncResult ar)
{
Console.WriteLine(“ReadCallback”);
string content=string.Empty;
//检索状态对象和处理程序套接字
//从异步状态对象。
StateObject状态=(StateObject)ar.AsyncState;
套接字处理程序=state.workSocket;
//从客户端套接字读取数据。
int bytesRead=handler.EndReceive(ar);
如果(字节读取>0)
{
//可能会有更多数据,因此请存储到目前为止收到的数据。
state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));
//检查文件结尾标记。如果不存在,请读取
//更多数据。
content=state.sb.ToString();
if(content.IndexOf(“”>-1)
{
//所有数据都已从数据库中读取
//客户端。在控制台上显示它。
WriteLine(“从套接字读取{0}字节。\n数据:{1}”,content.Length,content);
//继续阅读
state=新的StateObject();
handler.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
新的异步回调(ReadCallback),状态);
//我将此注释为当发送完成时,服务器关闭连接…我希望连接保持打开状态
//回显bac的数据
public static void ReadCallback(IAsyncResult ar)
{
    string content = string.Empty;

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar);

    if (bytesRead > 0)
    {
        Console.WriteLine("ReadCallback");

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

        // Check for end-of-file tag. If it is not there, read 
        // more data.
        content = state.sb.ToString();
        if (content.IndexOf("<EOF>") > -1)
        {
            // All the data has been read from the 
            // client. Display it on the console.
            Console.WriteLine("Read {0} bytes from socket. Data : {1}", content.Length, content);

            state = new StateObject();
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);

            // Echo the data back to the client.
            //                Send(handler, content);
        }
        else
        {
            // Not all data received. Get more.
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }
    }
}
public static void ReadCallback(IAsyncResult ar)
{
    string content = string.Empty;

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    // Read data from the client socket. 
    int bytesRead = handler.EndReceive(ar);

    if (bytesRead > 0)
    {
        Console.WriteLine("ReadCallback");

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

        // Check for end-of-file tag. If it is not there, read 
        // more data.
        content = state.sb.ToString();
        if (content.IndexOf("<EOF>") > -1)
        {
            // All the data has been read from the 
            // client. Display it on the console.
            Console.WriteLine("Read {0} bytes from socket. Data : {1}", content.Length, content);

            // Echo the data back to the client.
            Send(handler, content);
        }
        else
        {
            // Not all data received. Get more.
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }
    }

    // clear the state object's buffer and queue the next begin receive
    state.sb.Clear();
    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
    Console.WriteLine("ReadCallback");

    string content = string.Empty;

    // Retrieve the state object and the handler socket
    // from the asynchronous state object.
    StateObject state = (StateObject)ar.AsyncState;
    Socket handler = state.workSocket;

    // Read data from the client socket. 
    int bytesRead = handler.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));

        // Check for end-of-file tag. If it is not there, read 
        // more data.
        content = state.sb.ToString();
        if (content.IndexOf("<EOF>") > -1)
        {
            // All the data has been read from the 
            // client. Display it on the console.
            Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);

            // continue reading
            state = new StateObject();
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);

            // I commented this out as when the send completes, the server closes the connection... I want the connection to remain open
            // Echo the data back to the client.
            //Send(handler, content);
        }
        else
        {
            // Not all data received. Get more
            // start writing at bytesRead in the buffer so you don't lose the partially read data
            handler.BeginReceive(state.buffer, bytesRead, StateObject.BufferSize, 0,
        new AsyncCallback(ReadCallback), state);
        }
    }
}