NetWork WinForm:关于SOCKET启动

以前写SOCKET操作时都是用C#,FRAMEWORK提供得很方便,

其实也是自已研习得不深,只是会调,会用而已

最近帮同事写写C++,也接触到SOCKET。。。却很SBB。。。。(金融危机,一个人得做几个人的工作了)

参考了CODEPROJECT的一段代码,边看边写,

在实例化SOCKET时却总是出错

SOCKET socket(
int af,
int type,
int protocol
);

The socket function creates a socket that is bound to a specific service provider.


if( (m_hSocket=socket(AF_INET, nType, 0))==INVALID_SOCKET ) 都是TRUE。。。。

郁闷了,提示的异常也看不懂。

哎。C++真是一门难调的语言啊。。。。。

幸好这时同事过来帮忙下: int iLastError = WSAGetLastError();

返回10093,查了下错误号,这下才清楚了

Successful WSAStartup not yet performed.

Either the application has not called WSAStartup or WSAStartup failed. The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks), or WSACleanup has been called too many times.

 

原来还需调用WASStartup函数,可原代码里作者并没有呀,尽管自已添加进去可以运行了,但这下不死心了

在CSDN的前辈回复中无意看到这么个函数AfxSocketInit,查了一下:

“ 如果使用Platform SDK:Windows Sockets,在调用socket函数创建新的sockets之前要先调用WSAStartup函数。WSAStartup函数作用是引入 Ws2_32.dll库。根据MSDN上说,WSAStartup函数必须是应用程序或DLL调用的第一个Windows Sockets函数,它允许应用程序或者DLL指定需要的Windows Sockets版本和重新找回指定的Windows Sockets执行的细节。只有在成功的调用WSAStartup函数之后才能进一步使用接下来的Windows Sockets函数。

  同理,如果使用的是MFC包装的CSocket类,需要在调用Cresat创建新的套接字之前调用AfxSocketInit函数。AfxSocketInit函数包装的是WSAStartup函数,作用是相同的。”

 查了一下原代码,在InitInstance函数里真有

 if(!AfxSocketInit())
   {
      AfxMessageBox(_T("Sockets can't be initialized"));
      return FALSE;
   }

这下就都清楚了,原来作者是通过这个来启动SOCKET了。。。。。。

而MFC包装了这个方法。。。。为什么要这样呢?。。。。。以后再了解喽,好像说是平台调用的问题。。。。。

 在这里补充一个地址,关于SOCKET错误的,挺有用的

ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.WIN32COM.v10.en/winsock/winsock/windows_sockets_error_codes_2.htm

 

 还有GetLastError

[问题提出]

    GetLastError()返回的是DWORD数字,有的可以查到什么意思,有的却不行,如何解决?

  [程序实现]
    在你的工程中要用到GetLastError()时,这样写:
    {
       //获得信息
       LPVOID lpMsgBuf; //Windows will allocate
       ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,0, GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //默认语言
       (LPTSTR)&lpMsgBuf, 0, NULL );
       //显示
       ::MessageBox(0, (LPCTSTR)lpMsgBuf, _T("GetLastError"), MB_OK|MB_ICONINFORMATION );
       //lpMsgBuf中是你要的错误提示.
       //释放内存
       ::LocalFree( lpMsgBuf );
    } 


用了WINSOCK后才知道好多好多SOCKET的内容,以前的老WIN32 CODER真不容易啊,也真幸运。。。。

要加紧脚步学习SOCKET,也学习写点C++、MFC,嘿嘿。。。。认识到WINSOCK好多历史啊!兴奋中。。。

 

 

也发现好多人的一个写法,感觉挺不错的

“在START函数里调用STOP”。进行变量的初始化值的设置,还有关闭SOCKET等等资源的释放。

可能一个组件自已用调用顺序之类的都很清楚,

可如果是别人调用,那就不一定了,而这种写法,开始之前先做一次资源的初始化,能避免很多误操作,嘿嘿,不错 






posted @ 2008-11-25 16:25  yellowyu  阅读(836)  评论(0编辑  收藏  举报