你如何在C中编码?
所需的流程是:
Create socket
Create window
loop: Wait until data can be read from socket or message are added to the queue
if data then
do stuff with data
goto loop
else if message then
do stuff with message
goto loop
我试过这段代码:
MSG msg;
DWORD last=msg.time;
short bRet;
char command[20];
int n=0;
while((
(n = recv(sock, command, sizeof command - 1, 0)) >= 0
)||(
(bRet = GetMessage( &msg, 0, 0, 0 )) != 0
//I can't use peek message because it will have the same issue than non-blocking socket
)){
//here we check time of message if it is equal to last we know that is socket
}
我知道线程存在,但我想避免使用线程。如果这是唯一的方法,我将使用一个线程。
编辑: 使用非阻塞套接字不是解决方案,因为如果没有可用数据且队列中没有消息,那么我的程序将退出。
答案 0 :(得分:1)
WSAAsyncSelect函数请求基于Windows消息的基于消息的网络事件通知。
套接字将通知指定的HWND
套接字活动,如可用的数据。
然后,应用程序可以运行标准消息循环,处理来自队列的套接字消息。
#define WM_SOCKET_MSG (WM_APP + 1)
WSAAsyncSelect(sock, hwnd, WM_SOCKET_MSG, FD_READ | FD_WRITE | FD_CLOSE);
MSG msg;
char command[20];
int n;
while (GetMessage(&msg, 0, 0, 0)) {
switch (msg.message) {
case WM_SOCKET_MSG:
{
int event = WSAGETSELECTEVENT(msg.lParam);
int error = WSAGETSELECTERROR(msg.lParam);
if (error != 0) {
// process socket error as needed ...
break;
}
switch(event) {
case FD_READ:
n = recv(sock, command, sizeof command - 1, 0);
if (n > 0) {
// process data as needed ...
} else {
// process read error as needed ...
}
break;
}
// process other socket events as needed ...
}
break;
}
// process other messages as needed ...
}
}
答案 1 :(得分:1)
我肯定会为网络recv()和所有相关协议检查/解析分别使用一个线程,因此将其与消息处理循环隔离开来。这样的线程可以合理地移植。该线程将生成'命令' struct instances,(malloc),并将它们激活到extern处理函数中。在Windows上,该处理程序将结构地址加载到WM_APP消息的lParam / hParam中并将其发布到GetMessage()线程,在那里它将以通常的方式接收,调度到处理程序,提取,执行结构,然后释放。
这样的设计可能被视为过于复杂(并使用可怕的线程),但它比测试,调试,扩展和增强更容易,而不是将所有东西塞进一个完成所有事情的异步消息循环中。有时,额外的线程真的更容易:)