2016-07-28 22 views
0

我正在写一个简单的客户端服务器套接字程序,并不知道为什么我的客户端只发送第一次按下发送按钮。为什么无法在套接字连接上发送两次数据?

第二次“nwStream.Write(bytesToSend,0,bytesToSend.Length);”被称为,服务器不会获得数据...

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

请帮我将数据发送两次......

这里是C#FORM客户端代码

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"; 
    } 

} 

这里是窗体设计器代码:

partial class Form1 
{ 
    // <summary> 
    // Required designer variable. 
    // </summary> 
    private System.ComponentModel.IContainer components = null; 

    // <summary> 
    // Clean up any resources being used. 
    // </summary> 
    // <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 
    protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

    #region Windows Form Designer generated code 

    /// <summary> 
    /// Required method for Designer support - do not modify 
    /// the contents of this method with the code editor. 
    /// </summary> 
    private void InitializeComponent() 
    { 
     this.button_Start = new System.Windows.Forms.Button(); 
     this.button_Send = new System.Windows.Forms.Button(); 
     this.button_Close = new System.Windows.Forms.Button(); 
     this.textBox_MsgToSend = new System.Windows.Forms.TextBox(); 
     this.textBox_Received = new System.Windows.Forms.TextBox(); 
     this.textBox_IP = new System.Windows.Forms.TextBox(); 
     this.label1 = new System.Windows.Forms.Label(); 
     this.label2 = new System.Windows.Forms.Label(); 
     this.textBox_Sending = new System.Windows.Forms.TextBox(); 
     this.label3 = new System.Windows.Forms.Label(); 
     this.textBox_Size = new System.Windows.Forms.TextBox(); 
     this.SuspendLayout(); 
     // 
     // button_Start 
     // 
     this.button_Start.Location = new System.Drawing.Point(30, 28); 
     this.button_Start.Name = "button_Start"; 
     this.button_Start.Size = new System.Drawing.Size(75, 23); 
     this.button_Start.TabIndex = 0; 
     this.button_Start.Text = "Start"; 
     this.button_Start.UseVisualStyleBackColor = true; 
     this.button_Start.Click += new System.EventHandler(this.button_Start_Click); 
     // 
     // button_Send 
     // 
     this.button_Send.Location = new System.Drawing.Point(30, 73); 
     this.button_Send.Name = "button_Send"; 
     this.button_Send.Size = new System.Drawing.Size(75, 23); 
     this.button_Send.TabIndex = 1; 
     this.button_Send.Text = "Send"; 
     this.button_Send.UseVisualStyleBackColor = true; 
     this.button_Send.Click += new System.EventHandler(this.button_Send_Click); 
     // 
     // button_Close 
     // 
     this.button_Close.Location = new System.Drawing.Point(30, 172); 
     this.button_Close.Name = "button_Close"; 
     this.button_Close.Size = new System.Drawing.Size(75, 23); 
     this.button_Close.TabIndex = 2; 
     this.button_Close.Text = "Close"; 
     this.button_Close.UseVisualStyleBackColor = true; 
     this.button_Close.Click += new System.EventHandler(this.button_Close_Click); 
     // 
     // textBox_MsgToSend 
     // 
     this.textBox_MsgToSend.Location = new System.Drawing.Point(120, 73); 
     this.textBox_MsgToSend.Name = "textBox_MsgToSend"; 
     this.textBox_MsgToSend.Size = new System.Drawing.Size(207, 20); 
     this.textBox_MsgToSend.TabIndex = 3; 
     // 
     // textBox_Received 
     // 
     this.textBox_Received.Location = new System.Drawing.Point(120, 174); 
     this.textBox_Received.Name = "textBox_Received"; 
     this.textBox_Received.Size = new System.Drawing.Size(207, 20); 
     this.textBox_Received.TabIndex = 4; 
     // 
     // textBox_IP 
     // 
     this.textBox_IP.Location = new System.Drawing.Point(120, 28); 
     this.textBox_IP.Name = "textBox_IP"; 
     this.textBox_IP.Size = new System.Drawing.Size(128, 20); 
     this.textBox_IP.TabIndex = 5; 
     // 
     // label1 
     // 
     this.label1.AutoSize = true; 
     this.label1.Location = new System.Drawing.Point(117, 57); 
     this.label1.Name = "label1"; 
     this.label1.Size = new System.Drawing.Size(90, 13); 
     this.label1.TabIndex = 7; 
     this.label1.Text = "Message to Send"; 
     // 
     // label2 
     // 
     this.label2.AutoSize = true; 
     this.label2.Location = new System.Drawing.Point(117, 96); 
     this.label2.Name = "label2"; 
     this.label2.Size = new System.Drawing.Size(49, 13); 
     this.label2.TabIndex = 9; 
     this.label2.Text = "Sending:"; 
     // 
     // textBox_Sending 
     // 
     this.textBox_Sending.Location = new System.Drawing.Point(120, 112); 
     this.textBox_Sending.Name = "textBox_Sending"; 
     this.textBox_Sending.ReadOnly = true; 
     this.textBox_Sending.Size = new System.Drawing.Size(207, 20); 
     this.textBox_Sending.TabIndex = 8; 
     // 
     // label3 
     // 
     this.label3.AutoSize = true; 
     this.label3.Location = new System.Drawing.Point(330, 96); 
     this.label3.Name = "label3"; 
     this.label3.Size = new System.Drawing.Size(27, 13); 
     this.label3.TabIndex = 11; 
     this.label3.Text = "Size"; 
     // 
     // textBox_Size 
     // 
     this.textBox_Size.Location = new System.Drawing.Point(333, 112); 
     this.textBox_Size.Name = "textBox_Size"; 
     this.textBox_Size.ReadOnly = true; 
     this.textBox_Size.Size = new System.Drawing.Size(65, 20); 
     this.textBox_Size.TabIndex = 10; 
     // 
     // Form1 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.ClientSize = new System.Drawing.Size(447, 262); 
     this.Controls.Add(this.label3); 
     this.Controls.Add(this.textBox_Size); 
     this.Controls.Add(this.label2); 
     this.Controls.Add(this.textBox_Sending); 
     this.Controls.Add(this.label1); 
     this.Controls.Add(this.textBox_IP); 
     this.Controls.Add(this.textBox_Received); 
     this.Controls.Add(this.textBox_MsgToSend); 
     this.Controls.Add(this.button_Close); 
     this.Controls.Add(this.button_Send); 
     this.Controls.Add(this.button_Start); 
     this.Name = "Form1"; 
     this.Text = "Client"; 
     this.Load += new System.EventHandler(this.Form1_Load); 
     this.ResumeLayout(false); 
     this.PerformLayout(); 

    } 

    #endregion 

    private System.Windows.Forms.Button button_Start; 
    private System.Windows.Forms.Button button_Send; 
    private System.Windows.Forms.Button button_Close; 
    private System.Windows.Forms.TextBox textBox_MsgToSend; 
    private System.Windows.Forms.TextBox textBox_Received; 
    private System.Windows.Forms.TextBox textBox_IP; 
    private System.Windows.Forms.Label label1; 
    private System.Windows.Forms.Label label2; 
    private System.Windows.Forms.TextBox textBox_Sending; 
    private System.Windows.Forms.Label label3; 
    private System.Windows.Forms.TextBox textBox_Size; 
} 

现在服务器

服务器是一个控制台应用程序,它有两个类和一个主要的

// State object for reading client data asynchronously 
public class StateObject 
{ 
    // Client socket. 
     public Socket workSocket = 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(); 
} 

这里是服务器代码:

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()); 
     } 
    } 

这里是主要的:

public static int Main(String[] args) 
{ 
    StartListening("192.168.0.72"); 
    return 0; 
} 

尝试1:

我在公共静态无效AcceptCallback想这(IAsyncResult的AR )功能:

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

ATTEMPT2:

每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); 
     } 
    } 
} 

尝试3:

闯闯基于什么大卫说,但在函数结束时重置BeginReceive - WORKS!

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); 
} 
+0

该行你尝试下加1他是什么意思应该在if(content.IndexOf(“”> -1)块中。成功读取数据后,您需要让套接字重新读取。 – SpaceghostAli

+0

再次读取时,您可能需要清除缓冲区或调整写入位置,具体取决于您是否要追加它或丢弃之前读取的内容 – SpaceghostAli

回答

2

一旦您的服务器读取消息,然后将其写入控制台,它永远不会再次开始读取。它刚刚退出“ReadCallback”。服务器的连接保持打开状态,但不会再读取。

为了解决这个问题,你应该在写出最后收到的消息后再启动另一个“BeginReceive”。

+0

我试过了:while(true) handler.BeginReceive (state.buffer,0,StateObject.BufferSize,0,新的AsyncCallback(ReadCallback),状态); } - 没有工作..必须有一种方法来保持服​​务器响应客户端连接 – user3174075

+0

用你试过的新代码更新你的文章 – SpaceghostAli

+0

在我的文章中看到尝试3 - 谢谢你...所有 – user3174075

1

我upvoted大卫的答案,因为我相信这是正确的,所以请把它标记为这样的,这只是阐明根据您的更新

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); 
     } 
    } 
} 
相关问题