- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在通过 tcp 实现乒乓球。我有用 C# 编写的 Pinger。还有两只火锅。一个用 C# 编写,另一个用 C++ 编写。 Pinger 只是向 pongers 发送消息,pongers 回复他。问题是,当 C# ponger 工作时,一切正常,但是当 C++ ponger 工作时,来自 Pinger 的行
var res = client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
不运行回调 (ReceiveCallback)。 ReceiveCallback 只被调用一次(从 Receive 函数)。pinger 代码片段在这里:
private void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
} finally
{
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = 0;
try
{
// Read data from the remote device.
bytesRead = client.EndReceive(ar);
}
catch (ObjectDisposedException e)
{
Console.WriteLine(client.Connected);
if (_isDown)
return;
else
{
throw e;
}
}
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));
try
{
// Get the rest of the data.
var res = client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (ObjectDisposedException e)
{
if (_isDown)
return;
else
{
throw e;
}
}
}
else
{
// All the data has arrived; put it in _response.
if (state.sb.Length > 1)
{
_response = state.sb.ToString();
}
// Signal that all bytes have been received.
_receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
C# Ponger 在这里:
public void AsyncListenFor()
{
// Bind the socket to the local endpoint and listen for incoming connections.
while (_doPong)
{
try
{
_localEndPoint = new IPEndPoint(_ipAddress, _port);
if (!_listener.IsBound)
{
_listener = CreateSocket(_listener);
BindAndListen(_listener, _localEndPoint);
}
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
//Console.WriteLine("Waiting for a connection...");
_listener.Blocking = true;
_listener.BeginAccept(new AsyncCallback(AcceptCallback), _listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
catch (Exception e)
{
// здесь не будем показывать эксепшон WatchDog`у чтобы не перезагружать прогу
//(если автостартер не будет работать)
if (_listener != null)
{
try
{
//_listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//Socket dataSocket = AsyncSocket.EndAccept(_IAsyncResult);
_listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(false, 0));
_listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false);
}
catch (Exception e2)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e2.Message + "\n" + e2.StackTrace); }
try
{
_listener.Shutdown(SocketShutdown.Both);
}
catch (Exception e2)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e2.Message + "\n" + e2.StackTrace); }
try
{
_listener.Disconnect(false);
}
catch (Exception e2)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e2.Message + "\n" + e2.StackTrace); }
try
{
_listener.Close();
}
catch (Exception e2)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e2.Message + "\n" + e2.StackTrace); }
}
CLogger.WriteLog(CLogger.ELogLevel.ERROR, "");
CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e.Message + "\n" + e.StackTrace);
Thread.Sleep(1000);
}
}
}
public Socket CreateSocket(Socket listener)
{
if (listener != null)
{
try
{
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(false, 0));
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false);
}
catch (Exception e2)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e2.Message + "\n" + e2.StackTrace); }
try
{
_listener.Shutdown(SocketShutdown.Both);
}
catch (Exception e2)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e2.Message + "\n" + e2.StackTrace); }
try
{
_listener.Disconnect(false);
}
catch (Exception e2)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e2.Message + "\n" + e2.StackTrace); }
try
{
_listener.Close();
}
catch (Exception e2)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e2.Message + "\n" + e2.StackTrace); }
}
try
{
listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(false, 0));
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, false);
} catch (Exception e)
{
CLogger.WriteLog(CLogger.ELogLevel.ERROR, "Не смогли создать сокет:\t" + e.Message);
}
return listener;
}
public void BindAndListen(Socket listener, IPEndPoint localEndPoint)
{
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
} catch (Exception e)
{ CLogger.WriteLog(CLogger.ELogLevel.DEBUG, e.Message + "\n" + e.StackTrace); }
}
public 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);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
public 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)
{
// 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);
// Echo the data back to the client.
Send(handler, _progName);
}
else
{
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}
private void Send(Socket handler, String 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.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
private 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());
}
}
C++ Ponger 在这里:
// listen the sotket and send
WSADATA wsaData;
int iResult;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
int iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
while(true) {
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
LOG(logINFO) << "Could not initialize Winsock";
continue;
}
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// Create a SOCKET for connecting to server
ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ListenSocket == INVALID_SOCKET) {
LOG(logINFO) << "Could not create socket.";
WSACleanup();
continue;
}
// Setup the TCP listening socket
struct sockaddr_in client;
client.sin_family = AF_INET;
client.sin_port = htons(port_);
client.sin_addr.s_addr = inet_addr(ip_.c_str());
iResult = bind(ListenSocket, (struct sockaddr *)&client, sizeof(struct sockaddr_in));
if (iResult == SOCKET_ERROR) {
LOG(logINFO) << "Bind failed.";
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
continue;
}
iResult = listen(ListenSocket, 0);
if (iResult == SOCKET_ERROR) {
LOG(logINFO) << "listen failed";
closesocket(ListenSocket);
WSACleanup();
continue;
}
// Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL);
if (ClientSocket == INVALID_SOCKET) {
LOG(logINFO) << "accept failed";
closesocket(ListenSocket);
WSACleanup();
continue;
}
closesocket(ListenSocket);
// Receive until the peer shuts down the connection
do {
iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
if (iResult > 0) {
printf("Bytes received: %d\n", iResult);
// Echo the buffer back to the sender
iSendResult = send( ClientSocket, recvbuf, iResult, 0 );
if (iSendResult == SOCKET_ERROR) {
printf("send failed with error: %d\n", WSAGetLastError());
closesocket(ClientSocket);
WSACleanup();
continue;
}
printf("Bytes sent: %d\n", iSendResult);
}
else if (iResult == 0)
printf("Connection closing...\n");
else {
LOG(logINFO) << "recv failed";
closesocket(ClientSocket);
WSACleanup();
continue;
}
} while (iResult > 0);
}
最佳答案
除非我遗漏了什么,否则在您的 C++ 服务器中您实际上并没有关闭客户端的套接字。
在 recv 返回 0 表示正常断开连接的情况下,我们进入 else if (iResult == 0)
分支。然后我们打印“Connection closing...”并退出 do ...while
循环。我们实际上没有在任何地方调用 shutdown
或 closesocket
。
您的程序也有一个非传统的结构。通常像这样的简单服务器看起来像:
create the listen socket
bind the listen socket
listen
while (!needToShutdown)
accept
read client request
do work
send response
shutdown client socket
close client socket
// we are now shutting down
close listen socket
请注意,这里我们在接受客户端后不会关闭监听套接字。我们可以使用同一个监听套接字一个接一个地接受多个客户端。 Wikipedia有一个例子。 (让这个服务同时处理多个客户端太复杂了,无法在这里讨论。)
关于c# - AsyncCallback 没有被第二次调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16612047/
我需要实现线程以缩短紧凑型框架应用程序的加载时间。我想启动一个后台线程来调用外部 API,而主线程缓存一些表单。后台线程完成后,我需要再触发两个线程来填充数据缓存。 我需要后台线程能够执行回调方法,所
我的申请中还有另一个问题。我在 MainActivity 中使用以下代码从我的 ContactAdapter 中获取用户数据: private List loadContactData() {
我目前有以下相关代码片段: public class MyEntryPoint implements EntryPoint { private boolean areFieldsEnabled
我正在通过 tcp 实现乒乓球。我有用 C# 编写的 Pinger。还有两只火锅。一个用 C# 编写,另一个用 C++ 编写。 Pinger 只是向 pongers 发送消息,pongers 回复他。
我想通过List进入AsyncCallback在函数中 LoadHistoryAsync(List Items)但是result.AsyncState在 CallForNewData(IAsyncRe
我需要使用异步委托(delegate)调用一个函数,当我浏览 AsyncCallback 的教程时,我看到异步回调定义如下: static void CallbackMethod(IAsyncResu
我最近注意到以下模式,但我没有完全掌握 CompletedSynchronously 属性的用法: IAsyncResult channelOpenResult = channel.BeginOpen
下面的代码是不言自明的,我的问题也很简单: 为什么 AsyncCallback 方法“HandleConnect”不向“Connect”方法传播异常 以及如何传播它? public void
在做我的应用程序时,我厌倦了总是在 asynccallback onfailure 中实现相同的默认错误处理(显示消息、catch.printstacktrace 等)。 我想知道您是否可以进行通用治
嗨,我有一段代码使用套接字连接到服务器 Try 'Connect To The Server Dim socketclient As New TcpClient Dim suc
我有一个数组 premisasObtenidas,我想用从 GWT AsyncCallback 获取的内容来更新它。该调用工作正常,并且 onSuccess 的代码执行,但是当我尝试将其返回的内容添加
我想使用 .NET-FTP 库 ( http://netftp.codeplex.com )。该库提供 BeginOpenRead(string,AsyncCallback,object) 以使用异步
我有一个类可以检查用户的操作、验证数据并调用 AsyncCallBack 以确定它是否是有效条目。我在两个地方使用了相同的逻辑,一个是用户单击“确定”,另一个是“输入”。通过在一种情况下调用 Asyn
我有一个 AsyncCallback 调用,它联系我的 GWT-RPC 服务并检索一些数据。我试图将该数据存储到一个类中,该类具有一个静态方法来存储查询结果。但是,我注意到数据没有填充到静态数据成员中
正是问题所说的。 我已阅读给定 here 的 MSDN 文章,并且(除非我是盲人),看不到任何明确证实这一点的地方。 为了提供更多范围,我主要指的是 Socket 类中提供的 Socket.Begin
我希望你能在以下方面帮助我: 我有一个 WebService 方法,它应该返回一个 CompensationPlanReturnReturn 对象数组。该方法是这样调用的: //This is the
我正在学习套接字编程,我有以下功能: public void OnDataReceived(IAsyncResult asyn) 回调是这样设置的: pfnWorkerCallBack = new A
我写了一个 HttpListener 监听其中一个端口: httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), httpL
我有以下类试图充当简单的异步操作: public class AsyncLineWriter { private delegate void SynchronousWriteLineDeleg
我有一个 Stream 对象,我正在使用 BeginRead 开始(显然)读入缓冲区;读取完成后调用 AsyncCallback 函数。在此函数中,我可以检查用户是否想要获取下一个“ block ”并
我是一名优秀的程序员,十分优秀!