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