我正在使用winsock和C++来设置服务器应用程序.我遇到的问题是调用listen导致第一次机会异常.我猜通常这些可以被忽略(?)但是我发现其他人有同样的问题我在哪里导致应用程序偶尔挂起一次.任何帮助将不胜感激.
第一次机会例外是:
MyApp .exe 中0x*12345678*的第一次机会异常:0x000006D9:端点映射器不再提供端点.
我发现一些证据表明这可能是由socket引起的.我正在使用的代码如下所示.listen从底部调用第五行时发生异常.
m_accept_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_accept_fd == INVALID_SOCKET)
{
return false;
}
int optval = 1;
if (setsockopt (m_accept_fd, SOL_SOCKET, SO_REUSEADDR,
(char*)&optval, sizeof(optval)))
{
closesocket(m_accept_fd);
m_accept_fd = INVALID_SOCKET;
return false;
}
struct sockaddr_in local_addr;
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = INADDR_ANY;
local_addr.sin_port = htons(m_port);
if (bind(m_accept_fd, (struct sockaddr *)&local_addr,
sizeof(struct sockaddr_in)) == SOCKET_ERROR)
{
closesocket(m_accept_fd);
return false;
}
if (listen (m_accept_fd, 5) == SOCKET_ERROR)
{
closesocket(m_accept_fd);
return false;
}
Run Code Online (Sandbox Code Playgroud) 我在网上搜索过,但没找到任何东西......
有没有人有一个使用WinSock和OpenSSL的简单代码示例?我正在寻找一个简单的Visual C++ 2005或更高代码示例,它创建并打开winsock连接并使用OpenSSL应用必要的SSL设置并适当地释放所有资源.
我有一个基于Winsock的服务器应用程序,它使用Windows Winsock I/O完成端口.
因此,接受的每个连接与监听套接字相关联以开始接收通知(读取,写入,关闭等).
侦听套接字有100个待处理连接的积压.
一切都很好.
在某些时候,我想停止接受新的连接,同时保持与已连接的现有连接套接字的通信.
我想我可以做一个:
现在,选项#1给出了预期的结果; 我的应用程序不处理新连接,但它确实接受积压的数量(100).实际上是连接 - 我不想要它!
选项#2 ; 我能这样做吗?怎么样?在MSDN上也找不到谷歌.MSDN上的listen()文档说;
如果在已经侦听的套接字上调用listen函数,它将返回成功而不更改backlog参数的值.在后续调用侦听侦听套接字时将backlog参数设置为0不被视为正确重置,尤其是在套接字上存在连接时.
对我不好.
如果我能以安全的方式这样做,我会将它与选项#1结合起来,有效地停止在机器上建立任何新的连接(通过监听端口!).
选项#3实际上有效; 关闭侦听套接字后,我仍然可以与现有连接通信,并且积压已经消失(好吧,关闭监听套接字!).
我担心这种方法可能会产生一些副作用.谁能确认一下?
我有一个使用Winsock进行网络连接的程序,我们现在的一个要求就是将程序移植到Linux上.阻止我们这样做的唯一因素是Winsock.
我的问题是:我可以轻松地将其移植到Linux实现中吗?
是否有任何陷阱我应该注意,如果我只是包含适当的头文件,我必须要处理什么样的事情?
谢谢你的帮助!
我发布了代码,但由于法律原因,我不能不幸.但是,我们的代码确实使用了以下内容:
WSAStartup(..)
WSACleanup(..)
Socket(..)
sendto(..)
recvfrom(..)
ioctlsocket(..)
setsocketopt(..)
Run Code Online (Sandbox Code Playgroud) 此代码适用于使用阻塞套接字的HTTPS服务器:
request := '';
start := gettickcount;
repeat
if SSL_pending(ssl) > 0 then
begin
bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
if bytesin > 0 then
begin
buffer[bytesin] := #0;
request := request + buffer;
end
else break; // read failed
end; // pending
until (gettickcount - start) > LARGETIMEOUT;
// "request" is ready, though possibly empty
Run Code Online (Sandbox Code Playgroud)
SSL_pending()始终返回零,并且永远不会到达SSL_read().如果删除了SSL_pending()调用,则执行SSL_read().为什么SSL_pending()不指示可用的字节数?
请注意,如果您调用SSL_read()并且返回的字节数小于缓冲区大小,那么您已经阅读了所有内容并完成了操作.
如果传入的数据大于缓冲区大小,则第一个SSL_read()调用将填充缓冲区,您可以重复调用SSL_read(),直到无法填充缓冲区为止.
但是如果传入的数据是缓冲区大小的精确倍数,则最后一块数据填充缓冲区.如果您尝试另一个SSL_read()认为阻塞套接字上可能有更多数据,它会无限期挂起.因此,首先要检查SSL_pending().然而,这似乎不起作用.
你如何避免挂在最后的SSL_read()上?(我无法想象答案是非阻塞,因为这意味着你永远不能将SSL_read与阻塞一起使用.)
更新: 以下工作.显然SSL_pending()在第一个SSL_read()之后才起作用:
request := '';
repeat
bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
if bytesin > 0 then
begin …Run Code Online (Sandbox Code Playgroud) 我有一个sockaddr_storage包含远程主机的ipv4地址和端口.我之前没有见过这些struct,我不知道如何把它转换成struct我可以直接检索IP地址和端口号的地方.我试过谷歌搜索struct但没有找到任何东西.有关如何做到这一点的任何建议?
谢谢
我在这里有这个代码来从主机名中检索IP地址:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
winsock;
function GetIPFromHost(const HostName: string): string;
type
TaPInAddr = array[0..10] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe: PHostEnt;
pptr: PaPInAddr;
i: Integer;
begin
Result := '';
phe := GetHostByName(PChar(HostName));
if phe = nil then Exit;
pPtr := PaPInAddr(phe^.h_addr_list);
i := 0;
while pPtr^[i] <> nil do
begin
Result := inet_ntoa(pptr^[i]^);
Inc(i);
end;
end;
var
wsaData: TWSAData;
begin
if (WSAStartup($0202, wsaData) <> 0) then begin
Exit;
end;
while true do begin
sleep (1000);
GetIPFromHost …Run Code Online (Sandbox Code Playgroud) 该ConnectEx功能需要一个"未连接的,以前绑定的插座".实际上,如果我省略了我的示例中的绑定步骤(见下文),ConnectEx将失败并使用WSAEINVAL.
这是我目前的理解:在调用ConnectEx之前,将套接字绑定到INADDR_ANY端口0(除非它已绑定):
struct sockaddr_in addr;
ZeroMemory(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = 0;
rc = bind(sock, (SOCKADDR*) &addr, sizeof(addr));
if (rc != 0) { ... bind failed; call WSAGetLastError to see why ... }
Run Code Online (Sandbox Code Playgroud)
或者对于IPv6套接字:
struct sockaddr_in6 addr;
ZeroMemory(&addr, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_addr = in6addr_any;
addr.sin6_port = 0;
rc = bind(sock, (SOCKADDR*) &addr, sizeof(addr));
if (rc != 0) { ... …Run Code Online (Sandbox Code Playgroud) 阻塞和非阻塞Winsock TCP套接字通常存在速度或性能差异吗?我可以得到两个套接字的差异,但两种类型之间没有详细的性能比较.
我accept()在一个等待连接请求的线程中有一个阻塞调用.当应用程序即将关闭时,我想发信号正在等待accept()正常退出的线程.我在Winsock的文档中发现我可以为send()和设置超时值recv(),但我不能这样做accept().
我已经读过我可以使套接字无阻塞并使用select(),并传递超时值select(),但我正在寻找阻塞套接字的解决方案.