新手求教socketAPI调用错误
<p>新人到来先和大家打个招呼,请多多关照</p><p> </p>
<p>接触VB是前两天的事情,平时多用的是c++,所以VB里面有很多问题感觉很困惑</p>
<p> </p>
<p><font face="Verdana">本意是想写一个调用API的TCP,调用ws2_32.dll里面的socket/connect/recv/send函数</font></p>
<p> </p>
<p>结果错误连连,最后还是卡在一个地方无论如何都过不去了,因为连最初始的socket的无法创建=.=</p>
<p> </p>
<p>我的操作步骤如下:</p>
<p>建立一个带按钮的窗口,click中写</p>
<p><font face="Verdana">s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)</font></p>
<p>msgbox s</p>
<p>(AF_INET, SOCK_STREAM, IPPROTO_TCP)这3个参数在上面已经定义过了</p>
<p>建立一个模块中声明socket函数</p>
<p><font face="Verdana">Declare Function socket Lib "ws2_32.dll" (ByVal af As Long, ByVal s_type As Long, ByVal Protocol As Long) As Long</font></p>
<p> </p>
<p>结果无论怎么运行都是返回的都是创建失败的-1</p>
<p> </p>
<p>但是跑回c++下面试却是正常的,请问这个是什么问题?</p>
[此贴子已经被作者于2009-4-12 12:26:47编辑过] <p>我测试了一下,代码如下:</p>
<p> </p>
<p><font face="Verdana">Option Explicit</font></p>
<p><font face="Verdana">Private Const AF_INET As Long = 2<br/>Private Const SOCK_STREAM As Long = 1<br/>Private Const IPPROTO_TCP As Long = 6</font></p>
<p><font face="Verdana">Private Const WSANOTINITIALISED As Long = 10093&<br/>Private Const WSAENETDOWN As Long = 10050&<br/>Private Const WSAEAFNOSUPPORT As Long = 10047&<br/>Private Const WSAEINPROGRESS As Long = 10036&<br/>Private Const WSAEMFILE As Long = 10024&<br/>Private Const WSAEPROTONOSUPPORT As Long = 10043&<br/>Private Const WSAEPROTOTYPE As Long = 10041&<br/>Private Const WSAENOBUFS As Long = 10055&<br/>Private Const WSAESOCKTNOSUPPORT As Long = 10044&</font></p>
<p><font face="Verdana">Private Declare Function socket Lib "ws2_32.dll" (ByVal af As Long, ByVal s_type As Long, ByVal Protocol As Long) As Long</font></p>
<p><font face="Verdana">Private Sub Command1_Click()<br/> Dim S As Long<br/> S = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)<br/> <br/> MsgBox S<br/> Debug.Print Err.LastDllError<br/>End Sub</font></p>
<p> </p>
<p>Err.LastDllError返回的是<font face="Verdana">10093</font>,经查MSDN,<font face="Verdana">10093</font>是WSANOTINITIALISED:</p>
<p> </p>
<div class="msgheader">QUOTE:</div><div class="msgborder"><font style="BACKGROUND-COLOR: #ffffff"></font><b>
<h4>Error Codes</h4>
<table cellspacing="4" cols="2">
<tbody>
<tr valign="top">
<td width="46%">WSANOTINITIALISED</td>
<td width="54%">A successful <b>WSAStartup</b> must occur before using this function.</td></tr>
<tr valign="top">
<td width="46%">WSAENETDOWN</td>
<td width="54%">The network subsystem or the associated service provider has failed.</td></tr>
<tr valign="top">
<td width="46%">WSAEAFNOSUPPORT</td>
<td width="54%">The specified address family is not supported.</td></tr>
<tr valign="top">
<td width="46%">WSAEINPROGRESS</td>
<td width="54%">A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</td></tr>
<tr valign="top">
<td width="46%">WSAEMFILE</td>
<td width="54%">No more socket descriptors are available.</td></tr>
<tr valign="top">
<td width="46%">WSAENOBUFS</td>
<td width="54%">No buffer space is available. The socket cannot be created.</td></tr>
<tr valign="top">
<td width="46%">WSAEPROTONOSUPPORT</td>
<td width="54%">The specified protocol is not supported.</td></tr>
<tr valign="top">
<td width="46%">WSAEPROTOTYPE</td>
<td width="54%">The specified protocol is the wrong type for this socket.</td></tr>
<tr valign="top">
<td width="46%">WSAESOCKTNOSUPPORT</td>
<td width="54%">The specified socket type is not supported in this address family.</td></tr></tbody></table></b></div>
<p> </p>
<p>也就是说,看起来你需要先调用一下<b>WSAStartup吧...</b></p> <p>我不是不想用WSAstartup</p>
<p> </p>
<p>只是我只要调用WSAstartup整个VB6.0就直接报错关闭</p>
<p> </p>
<p>是不是我的变量定义有问题?</p>
<p> </p>
<p>声明:</p>
<p><font face="Verdana">Public Declare Function WSAStartup Lib "ws2_32.dll" (ByVal wVersionRequired As Long, lpWSAData As WSAData) As Long</font></p>
<p> </p>
<p><font face="Verdana">Type WSAData<br/> wVersion As Integer<br/> wHighVersion As Integer<br/> szDescription As String<br/> szSystemStatus As String<br/> iMaxSockets As Integer<br/> iMaxUdpDg As Integer<br/> lpVendorInfo As Long<br/>End Type</font></p>
<p>代码段:</p>
<p>Dim Wstart as WSAData</p>
<p>Dim start as long</p>
<p>start = WSAStartup(&H202, Wstart)</p> <p>又调试对了</p>
<p> </p>
<p>不过还是不明白为什么</p>
<p>Dim Wstart as WSAData</p>
<p>call <font face="Verdana">WSAStartup(&H202, Wstart)</font></p>
<p> </p>
<p>和</p>
<p> </p>
<p>Dim Wstart as WSAData</p>
<p>Dim start as long</p>
<p>start = WSAStartup(&H202, Wstart)</p>
<p> </p>
<p>之间有什么区别么?为什么上面的那个运行就报错,下面的就正常呢?</p> <div class="msgheader">QUOTE:</div><div class="msgborder"><b>以下是引用<i>fhmily</i>在2009-4-12 14:40:14的发言:</b><br/>
<p>我不是不想用WSAstartup</p>
<p> </p>
<p>只是我只要调用WSAstartup整个VB6.0就直接报错关闭</p>
<p> </p>
<p>是不是我的变量定义有问题?</p>
<p> </p>
<p>声明:</p>
<p><font face="Verdana">Public Declare Function WSAStartup Lib "ws2_32.dll" (ByVal wVersionRequired As Long, lpWSAData As WSAData) As Long</font></p>
<p> </p>
<p><font face="Verdana">Type WSAData<br/> wVersion As Integer<br/> wHighVersion As Integer<br/> szDescription As String<br/> szSystemStatus As String<br/> iMaxSockets As Integer<br/> iMaxUdpDg As Integer<br/> lpVendorInfo As Long<br/>End Type</font></p>
<p>代码段:</p>
<p>Dim Wstart as WSAData</p>
<p>Dim start as long</p>
<p>start = WSAStartup(&H202, Wstart)</p></div>
<p>你这里的这个WSAData结构声明有问题.</p>
<p> </p>
<p>结构原型:</p>
<p> </p>
<p><font face="Verdana">struct WSAData {<br/> WORD wVersion;<br/> WORD wHighVersion;<br/> char szDescription;<br/> char szSystemStatus;<br/> unsigned short iMaxSockets;<br/> unsigned short iMaxUdpDg;<br/> char FAR * lpVendorInfo;<br/>};</font></p>
<p> </p>
<p>可见szDescription与szSystemStatus两个成员不是字符串指针,而是初始化好的两个缓冲区.</p>
<p> </p>
<p>正确的VB6声明应该是这样:</p>
<p> </p>
<p><font face="Verdana"><strong>Private Const WSA_DESCRIPTIONLEN = 256<br/>Private Const WSA_DescriptionSize = WSA_DESCRIPTIONLEN + 1<br/>Private Const WSA_SYS_STATUS_LEN = 128<br/>Private Const WSA_SysStatusSize = WSA_SYS_STATUS_LEN + 1</strong></font></p>
<p><strong></strong> </p>
<p><font face="Verdana"><strong>Private Type WSADATA<br/> wVersion As Integer<br/> wHighVersion As Integer<br/> szDescription As String * WSA_DescriptionSize<br/> szSystemStatus As String * WSA_SysStatusSize<br/> iMaxSockets As Integer<br/> iMaxUdpDg As Integer<br/> lpVendorInfo As Long<br/>End Type<br/></strong></font></p>
<p><font face="Verdana">如果按你的那种声明,两个字符串参数传进去后,WSAStartup函数肯定会发生内存写入范围的不正常,因为变长STRING未初始化时,只有那个指针占了4字节而已....</font></p>
<p><font face="Verdana"></font> </p>
<p><font face="Verdana">那如果写入长度太长,超过了整个结构的长度,就会发生错误了;</font></p>
<p><font face="Verdana"></font> </p>
<p><font face="Verdana">假如运气好,返回的字符串短,没超过,则不会崩溃,但返回的值肯定不对头.</p></font> <p>不熟悉VB,在慢慢的摸索,经常出一些莫名其妙的问题</p>
<p> </p>
<p>最后还是用VC先做了,不过说实话不甘心啊,还是想把这段东西弄明白</p>
<p> </p>
<p>热心的版主再点拨我一下吧=.=</p>
<p> </p>
<p>API中的这个函数</p>
<p>u_short WSAAPI htons(<br/> __in u_short <em>hostshort</em><br/>);<br/></p>
<p>原理其实就是把一个word中的2个16位进行颠倒</p>
<p>但是VB里面没有unsign类型数据,如果用integer的话会溢出,而long的话又无法带入其它函数中,这种情况该如何处理呢?</p> <p>"无法带入其它函数中"作何解释呢?</p>
<p> </p>
<p>以下是我的测试代码:</p>
<p> </p>
<p><font face="Verdana">Option Explicit</font></p>
<p> </p>
<p><font face="Verdana">Private Declare Function htons Lib "ws2_32.dll" ( _<br/> ByVal hostshort As Integer) As Integer</font></p>
<p> </p>
<p><font face="Verdana">Private Sub Command1_Click()<br/> MsgBox Hex(htons(&H3498))<br/>End Sub</font></p>
<p> </p>
<p>INTEGER是2字节,而htons是对WORD高低位反一下,只要输入的值是2字节,理论上不会溢出的.</p>
<p> </p>
<p>另外,欢迎讨论!</p> <p>&H是不是C++里面的0x?</p>
<p> </p>
<p>如果是的话我就明白问题出在哪里了</p>
<p> </p>
<p>等这两天忙完了好好的从头把那段程序用VB做一次</p>
<p> </p>
<p>最后还是谢谢版主,这么热心的版主这年头太太太难见到了,以后会经常来论坛学习的</p>
页:
[1]