我已经开始编写一个使用套接字的ActiveX控件.
使用此控件的应用程序可能也可能不使用套接字.我的控件是否可以判断是否已调用WSAStartup?
如果没有,请拨打电话.一个小小的测试表明,多次调用WSAStartup是很容易的.但是如果要求使用不同的winsock版本会发生什么?这会破坏应用程序的其他部分吗?
WSAStartup函数如何启动Winsock DLL的使用?
根据文件
WSAStartup函数必须是应用程序或DLL调用的第一个Windows套接字函数.它允许应用程序或DLL指定所需的Windows套接字版本,并检索特定Windows套接字实现的详细信息.应用程序或DLL只能在成功调用WSAStartup后发出更多Windows套接字函数.
这个函数初始化WSADATA数据结构,但在socket编程,我们不传递WSDATA任何功能,因此程序如何来了解Windows套接字版本和其他细节?
例如,在此代码中
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32")
void Run(int argc, char* argv[])
{
char* host = argc < 2 ? "" : argv[1];
struct hostent* entry = gethostbyname(host);
if(entry)
{
struct in_addr* addr = (struct in_addr*) entry->h_addr;
printf("IP Address: %s\n", inet_ntoa(*addr));
}
else
printf("ERROR: Resolution failure.\n");
}
int main(int argc, char* argv[])
{
WSADATA wsaData;
if(WSAStartup(0x202, &wsaData) == 0)
{
Run(argc, argv);
WSACleanup();
}
else
printf("ERROR: Initialization failure.\n");
}
Run Code Online (Sandbox Code Playgroud)
在这个例子中,我正在 …
我刚刚安装了Windows 10,Visual Studio Community 2015和Git for Windows.我还安装了最新的Bitbucket和GitHub扩展.
在Visual Studio中,我克隆了我的Bitbucket.com托管的存储库,并成功执行了这些操作:
$ git --version
git version 2.19.2.windows.1
$ git pull
Already up to date.
Run Code Online (Sandbox Code Playgroud)
但是当我试图从另一个存储库中提取时,我收到了这个错误:
$ git pull git://github.com/aegif/CmisSync.git
fatal: unable to lookup github.com (port 9418) (Either the application has not called WSAStartup, or WSAStartup failed. )
Run Code Online (Sandbox Code Playgroud)
我能ping通github.com.
我该如何调查并解决问题?
我有一个c ++ win32程序,它使用套接字从服务器下载一些数据.
在Windows上使用套接字之前,必须调用WSAStartup.MSDN说:"每次成功调用WSAStartup都必须调用WSACleanup.只有最后的WSACleanup函数调用才能执行实际的清理."
对我来说最简单的方法是每次从服务器下载数据时都调用WSAStartup/WSACleanup.大多数情况下,一次只有一个连接,因此WSACleanup将执行实际的清理.
这就是为什么我想知道WSAStartup和WSACleanup的成本是多少?我的意思是进行实际清理.如果与整个套接字连接相比,对WSAStartup和WSACleanup的调用只持续很短的时间,那么我可以使用简单的方法.如果没有,我应该在退出程序时注意调用WSACleanup.
以下是我执行的内容
D:\Just4Fun\software\>make -f Makefile.hands stest
g++.exe -g -D_WIN32_WINNT=0x0601 -ID:\Boost\boost_1_51_0 -LD:\Boost\boost_1_51_0\stage\lib -LD:\MinGW\lib -lboost_system-mgw46-d-1_51 -lboost_filesystem-mgw46-d-1_51 -lboost_iostreams-mgw46-d-1_51 -lws2_32 -lwsock32 -o TestSerial.exe TestSerial.cpp
以下是结果
C:\Users\oleg\AppData\Local\Temp\ccXpC7RG.o: In function 'ZN5boost4asio6detail17winsock_init_base7startupERNS2_4dataEhh':
D:/Boost/boost_1_51_0/boost/asio/detail/impl/winsock_init.ipp:39: undefined reference to 'WSAStartup@8'C:\Users\oleg\AppData\Local\Temp\ccXpC7RG.o: In function 'ZN5boost4asio6detail17winsock_init_base7cleanupERNS2_4dataE':
D:/Boost/boost_1_51_0/boost/asio/detail/impl/winsock_init.ipp:48: undefined reference to 'WSACleanup@0'
collect2: ld returned 1 exit status
make: *** [stest] Error 1
下面是检查库提到的symobls的结果(我没有以适当的方式格式化它)
`d:\ MinGW\lib> nm -C libws2_32.a | grep WSAStartup
00000000 T WSAStartup @ 8
00000000 I imp _WSAStartup @ 8
d:\ MinGW\lib> nm -C libws2_32.a | grep WSACleanup
00000000 T WSACleanup @ …
我正在使用Code :: Blocks,MinGW和Windows.我试图初始化winsock,以便我可以在项目上工作.我一直在收到错误Undefined Reference to WSAStartup@8任何人都知道如何解决这个问题?
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc , char *argv[]){
WSADATA wsa;
int output;
output=WSAStartup(MAKEWORD(2,2),&wsa);
if(output != 0) {
printf("Startup failed %d\n", output);
return 1;
} else {
printf("Initialized");
return 0;
}
}
Run Code Online (Sandbox Code Playgroud) 可以通过atExit函数注册WSACleanup吗?我们有几个应用程序可以在代码中的不同点终止,因此我们希望避免在代码中将WSACleanup放在任何地方.我们可以通过DllMain调用WSAStartup/WSACleanup,因为我们有一个所有这些应用程序都使用的dll.但是,Microsoft严格建议不要通过DllMain使用WSAStartup/WSACleanup,因为这会导致死锁.我们可以将WSAStarup移出DllMain,并在访问Windows套接字库之前在所有应用程序的代码中的某一点调用它.而且,只要我们调用WSAStartup,我们就想使用atExit函数来注册对WSACleanup的调用.有没有人有这种方法的经验?谢谢!
如果使用CreateProcessWithLogonW或CreateProcessAsUserW创建进程,则使用我自己的程序或其他程序在调用时无法运行winsock。创建套接字时,它将返回此错误:
Run Code Online (Sandbox Code Playgroud)WSAEPROVIDERFAILEDINIT 10106服务提供商初始化失败。
Run Code Online (Sandbox Code Playgroud)The requested service provider could not be loaded or initialized.如果无法加载服务提供商的DLL(LoadLibrary失败)或提供商的WSPStartup或NSPStartup函数失败,则返回此错误
。
但是,WSAStartup似乎没有错误。只需使用WSASocket创建套接字即可返回此结果。
更新:
错误:
LoadUserProfile:错误代码2。找不到指定的文件
AdjustTokenPrivs:错误代码5。访问被拒绝
我正在开发一个具有一个TCP服务器和几个UDP服务器/监听器的应用程序.每个服务器都是一个单独的线程,与已建立的TCP连接的工作线程相同.我在每个线程中调用WSAStartup().
有时,调用WSAStartup()会挂起(对我来说看起来像是一个死锁).这是堆栈跟踪:
ntdll.dll!_KiFastSystemCallRet@0()
ntdll.dll!_ZwWaitForSingleObject@12() + 0xc bytes
ntdll.dll!_RtlpWaitForCriticalSection@4() + 0x8c bytes
ntdll.dll!_RtlEnterCriticalSection@4() + 0x46 bytes
ntdll.dll!_LdrpGetProcedureAddress@20() + 0x17d bytes
ntdll.dll!_LdrGetProcedureAddress@16() + 0x18 bytes
kernel32.dll!_GetProcAddress@8() + 0x3e bytes
vld.dll!03203723()
[Frames below may be incorrect and/or missing, no symbols loaded for vld.dll]
ws2_32.dll!CheckForHookersOrChainers() + 0x22 bytes
ws2_32.dll!_WSAStartup@8() + 0xa7 bytes
Run Code Online (Sandbox Code Playgroud)
这种死锁发生在初始化时.我看到TCP服务器已启动,并且已建立一个TCP连接,而只启动了一个UDP服务器.堆栈跟踪来自应启动其余UDP服务器的功能.我的猜测是,当我尝试初始化UDP服务器并调用WSACStartup()时,另一个步骤是处理另一个套接字操作,例如新的TCP连接,它还调用WSAStartup()?
我的问题是从几个线程调用WSAStartup()是否会导致这种死锁?我检查的是在死锁之前调用的WSACleanup(),但事实并非如此.执行永远不会到达任何WSACleanup().
我知道只有一次调用WSAStartup就足够了,但是多次调用WSAStartup()应该不是问题(MSDN)1):"如果需要获取WSADATA结构信息,应用程序可以多次调用WSAStartup不止一次." 因此,我想确定这个死锁是由WSAStartup()还是其他原因造成的.
我有一个Windows套接字程序(XP及更高版本),该程序可以调用WSAStartup。WSACleanup在程序退出之前是否需要调用?如果我不这样做,会不会有负面影响?特别是:
WSACleanup();
exit(0);
Run Code Online (Sandbox Code Playgroud)
不同于仅仅exit(0)。我意识到在Win16 WSACleanup上仍然会泄漏系统资源。