我正在使用非阻塞套接字(fd_sets和select函数)编写服务器和客户端,一旦服务器关闭或关闭客户端套接字,客户端就会开始接收大量垃圾直到它崩溃.我已经被警告过,当工作时用select()插座将成为可读当连接被终止,但我怎么能知道
if( FD_ISSET( socket, &read ) )
{
}
Run Code Online (Sandbox Code Playgroud)
如果原因只是常规数据或连接已结束?
非常感谢!
根据MSDN:
hEvent:如果在没有I/O完成例程(操作的lpCompletionRoutine参数设置为null)的情况下发出重叠I/O操作,则此参数应包含WSAEVENT对象的有效句柄或为null.
当我使用IOCP时,当我调用WSASend()或WSARecv()时,我将NULL传递给它们的最后一个参数(即lpCompletionRoutine):
WSASend(pIoRequest->GetSocket(), pIoRequest->GetWsaBuffer(), 1, NULL, pIoRequest->GetFlags(), pIoRequest, NULL);
WSARecv(pIoRequest->GetSocket(), pIoRequest->GetWsaBuffer(), 1, NULL, &(pIoRequest->GetFlags()), pIoRequest, NULL);
Run Code Online (Sandbox Code Playgroud)
我的"每个I/O数据"类(pIoRequest)看起来像:
class IoRequest : public WSAOVERLAPPED
{
public:
IoRequest()
{
...
SecureZeroMemory(this, sizeof(WSAOVERLAPPED));
hEvent = WSACreateEvent(); // A
}
...
void ResetForNextIoRequest()
{
WSACloseEvent(hEvent); // B
SecureZeroMemory(this, sizeof(WSAOVERLAPPED));
hEvent = WSACreateEvent(); // C
...
}
...
DWORD& GetFlags() { return m_dwFlags; }
...
private:
...
DWORD m_dwFlags;
...
};
Run Code Online (Sandbox Code Playgroud)
即使我注释掉上面标记为A,B和C的行,它似乎对我的程序的行为没有任何影响.
那么如何决定何时调用WSACreateEvent()或者只是将hEvent设置为NULL?
我有一个使用的C程序getaddrinfo().它在Linux和Mac OS X上按预期工作.
我正在将它移植到Windows.
当我编译它(使用MinGW gcc)时,我收到以下警告:
ext/socket/socket.c: In function 'sl_tcp_socket_init':
ext/socket/socket.c:98:5: warning implicit declaration of function 'getaddrinfo' [-Wimplicit-function-declaration]
ext/socket/socket.c:104:9: warning implicit declaration of function 'freeaddrinfo' [-Wimplicit-function-declaration]
Run Code Online (Sandbox Code Playgroud)
然后整个事情无法链接到未定义的引用getaddrinfo()和freeaddrinfo().
现在,根据这个MSDN页面,getaddrinfo()Windows支持并位于头文件Ws2tcpip.h和库文件中Ws2_32.lib.
我包括Ws2tcpip.h并链接-lWs2_32,所以我不确定为什么这不起作用.
我正在写一个小型3服务器和1个客户端程序.2个服务器发送tcp消息,最后一个使用winsock2发送upd数据报.
我想知道我是否可以通过使用线程(OpenMP或boost :: threads)来模拟recvfrom(),以便2个线程同时从同一端口上的同一个套接字进行监听.
我在windows7上使用VC++ 2010.
谢谢您的帮助.
我可以轻松地使用“ win套接字”来实现HTTP,但是我一直在努力使用“ SChannel”来实现HTTPS,而“至少对我来说”的文献很少。如何建立用于HTTPS通信的安全连接,我应该注意任何安全性或性能方面的考虑吗?
因此,我一直在研究正在构建的服务器应用程序的套接字的重叠IO,并且不断看到有人说“从不使用hEvent”或“ IO完成端口会更快”的评论,但是没人能说为什么不要使用hEvent,也没有人在完成端口上提供更快或更快的真实数据或编号。hEvent可以WaitForMultipleObjects()更好地适合我的应用程序,因此,如果速度差异很小,我倾向于使用它,但是我不想在没有一些实际数据告诉我在此做出多大牺牲的情况下致力于这一点。我已经在Google,Google和Google上进行了搜索,除了一些StackOverflow回答说“不要使用这个”之外,找不到任何基准或文章,也无法对这两种策略进行比较。
有人可以在此处为我提供一些有关使用hEvent和完成端口之间的实际,实际差异的真实信息或数字吗?
对于我的Uni任务,我必须创建一个快节奏的网络游戏,因此选择使用UDP而不是TCP.我知道在UDP和TCP编程方面存在很多差异,并且已经阅读了关于winsock的MSDN文档的大部分相关部分.在MSDN上,它声明通过connect()函数创建UDP套接字应该将套接字绑定到指定的地址和端口,因此可以使用send()和recv()函数与创建的套接字.
对于我的应用程序,我创建一个客户端并使用loopback地址使用connect(),该地址通过send()函数发送大量数据包.客户端在调用select()之后,然后接收它发出的数据包.但是我从recv()函数得到的结果是SOCKET_ERROR,使用WSAGetLastError()的错误描述是"现有连接被远程主机强行关闭".
如果我使用bind()函数并使用sendto()通过环回地址发送数据,我recv()数据包没有任何错误...有谁知道为什么connect()函数没有做它应该做的事情,有没有人能够使用UDP套接字与connect()函数?
我正在使用消息窗口和WSAAsyncSelect.如何通过一个消息窗口跟踪多个套接字(客户端)?
我想要一个WSARecv精度.
基本上你似乎可以使用带有WSABUF数组的函数.
1-在没有完成端口的重叠I/O上下文中,假设我在具有48个WSABUF数组的数据报套接字上使用WSARecv(),这是否意味着我可以在一个数据包中接收48个不同的UDP数据包(每个缓冲区1个数据包)打电话(说他们到达同一时刻)?或者接收48个数据包的唯一方法是在事件发出信号后使用WSARecv()48次(使用带事件的重叠I/O但不是完成端口,我再说一遍).
2-在一个上下文WITH I/O完成端口/重叠的I/O,它意味着我可以更换这个
int n = 48;
for (int i = 0; i < n; i++)
WSARecv(sock, &buffer_array[i], 1, NULL, 0, &overlapped, completion_routine);
Run Code Online (Sandbox Code Playgroud)
有了这个?
WSARecv(sock, buffer_array, 48, NULL, 0, &overlapped, completion_routine);
Run Code Online (Sandbox Code Playgroud)
基本上它是否意味着调用带有48个缓冲区的WSARecv()将发布48个读取请求?
3-如果不是,一组WSABUF的目的是什么?我的意思是,只有一个正确的尺寸就足够了吗?
非常感谢!
我想编写一个客户端/服务器应用程序,客户端和服务器可以在其中交换消息。
Client site communication:
send
recv
send
recv
Server site communication:
recv
send
recv
send
Run Code Online (Sandbox Code Playgroud)
但是,我有一个问题,因为只有一条消息是发送/接收。之后,套接字关闭,不再发送进一步的消息。出了什么问题,如何解决这个问题?谢谢你。
服务器代码:
#undef UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment (lib, "Ws2_32.lib")
#define DEFAULT_PORT "27501"
#define SIZE 1024
int SendAllToClient(SOCKET ClientSocket, char *buffer)
{
int iSendResult;
int total = 0, len = 1024;
int bytesleft = 1024;
while( total < len )
{
iSendResult = send( ClientSocket, buffer, 1024, NULL);
if (iSendResult == SOCKET_ERROR)
{
printf("send failed …Run Code Online (Sandbox Code Playgroud)