Tjena.. orkar inte skriva om ett newsgroup inlägg jag skickat in, så Vild chansning från en som inte vet vad han snackar om. Men borde det inte vara: Nope, eftersom jag inte deklarerar parametrarna för RtlMoveMemory (copyemmory är bara ett alias för det api anropet) som As Any, utan använder mig av As Long istället.Winsock 2 API (på engelska)
denna får bli på engelska rakt igenom..
=========================================
I'm tryin to use the "pfnCondition" paramater in the WSAAccept API
to setup a condition check to decide if to accept or reject incomming
connections on my socket.
However, I cant seem to get it to work. All the parameters passed to
the callback function (ConditionFunc) are always zero, excpect for
the lpCallerId and lpCalleeId parameters. What I need to get it a
valid lpCallerData pointer.
Just to set up some background information, I create overlapped
sockets on both the client and server side using code that looks like
this
lhRemoteSocket = WSASocket(AF_INET, _
SOCK_STREAM, _
IPPROTO_IP, _
0, 0, _
WSA_FLAG_OVERLAPPED)
If lhRemoteSocket = INVALID_SOCKET Then
Debug.Print "Error: Invalid socket"
End If
The above code it from the client application, but there is an
identical setup for the server application (it uses a socket handler
called lhLocalSocket thats all). The declaration for the WSASocket
API is
WSASocket(Byval af As Long, Byval Type As Long, Byval protocol As Long,
Byval lpProtocolInfo As Long, Byval g As Long, Byval dwFlags As Long) As
Long
It's defined in an IDL file and for you that can read IDL code here
is the declaration for it (it's in a module poiunted to the ws2_32.dll)
#ifdef UNICODE
[entry("WSASocketW")]
#else
[entry("WSASocketA")]
#endif
LONG WSASocket(
[in] LONG af,
[in] LONG type,
[in] LONG protocol,
[in] LONG lpProtocolInfo,
[in] LONG g,
[in] LONG dwFlags);
On the server side I then bind, listen etc and start listen for incomming
connections (btw I can establish a connection between the server and
client without any problem, so I know theres no problem in the setup)
On client side I send of a WSAConnect call that looks like this
Dim CallerData As WSABUF
Dim hHeap As Long
hHeap = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1000)
With CallerData
.buf = hHeap
.Len = HeapSize(GetProcessHeap(), 0, hHeap)
End With
' Try to establish connection with the remote socket
lRet = WSAConnect(lhRemoteSocket, mRemoteAddr, Len(mRemoteAddr),
VarPtr(CallerData), 0, 0, 0)
If lRet = SOCKET_ERROR Then
Debug.Print "Error (" & WSAGetLastError() & ") Couldn't connect on
remote host"
End If
As you can see, I just set up a 1000 memory block of zero's and then send
it of with the connection call. I'm just using the VarPtr() call to get the
address
of the buffer to send (it's because i've made it ByVal ... As Long, instead
of
ByRef ... As WSABUF, ... this makes it possible for me to set it to null
(zero)
if I dont want to use it. Please dont rcommend As Any, since it's a
sloppyway
of doing thins, that is if it wont fix my problem which i doubt since I've
already
tried it ;)))
The API declaration for WSAConnect looks like this
WSAConnect(ByVal s As Long, ByRef name As Any, ByVal namelen As Long, _
ByVal lpCallerData As Long, ByVal lpCalleeData As Long, ByVal lpSQOS As
Long, _
ByVal lpGQOS As Long) As Long
Again I've made the lp*** into ByVal ... As Long to pass the pointer
directly. The
underlaying IDL looks like this for people that can read it
[entry("WSAConnect")]
LONG WSAConnect(
[in] LONG s,
[in, out] void * name,
[in] LONG namelen,
[in] LONG lpCallerData,
[in] LONG lpCalleeData,
[in] LONG lpSQOS,
[in] LONG lpGQOS);
On the server side I do the following when I catch the FD_ACCEPT network
event message.
lhNewSock = WSAAccept(lhLocalSocket, mIncommingAddr, _
Len(mIncommingAddr), _
AddressOf AcceptConditionFunc,
0)
The AcceptConditionFunc looks like this as the moment
Public Function AcceptConditionFunc( _
ByVal lpCallerId As Long, _
ByVal lpCallerData As Long, _
ByVal lpSQOS As Long, _
ByVal lpGQOS As Long, _
ByVal lpCalleeId As Long, _
ByVal lpCalleeData As Long, _
ByVal g As Long, _
ByVal dwCallbackData As Long) As Long
Debug.Print "lpCallerId: " & lpCallerId
Debug.Print "lpCallerData: " & lpCallerData
Debug.Print "lpSQOS: " & lpSQOS
Debug.Print "lpGQOS: " & lpGQOS
Debug.Print "lpCalleeId: " & lpCalleeId
Debug.Print "lpCalleeData: " & lpCalleeData
AcceptConditionFunc = CF_ACCEPT
End Function
Now since I did pass a WSABUF structure in the WSAConnect call, I'm
expecting
the lpCallerData to be nonzero, meaning a pointer to a structure on the
recieving side
so I could do something like this
Dim InData As WSABUF
CopyMemory VarPtr(InData), lpCallerData, Len(InData)
Debug.Print InData.Len
And get 1000 as a print out, but since my lpCallerData is always zero I cant
do the
copy and take part of the data that came with the connection request. I can
also
add that I know that the AcceptConditionFunc is called on connection
requests, since
I see the print outs in teh immediate window.
The API declare for WSAAccept looks like this
WSAAccept(ByVal s As Long, ByRef Addr As Any, ByRef addrlen As Long, _
ByVal lpfnCondition As Long, ByVal dwCallbackData As Long) As Long
And the underlayign IDL looks like this
[entry("WSAAccept")]
LONG WSAAccept(
[in] LONG s,
[out] void * addr,
[in, out] LONG * addrlen,
[in] LONG lpfnCondition,
[in] LONG dwCallbackData);
Just so noone post a reply asking such a simple thing, here is the
declaration of
the WSABUF srtrucutre as well (in idl only)
typedef struct WSABUF {
LONG len;
LONG buf;
} WSABUF, *LPWSABUF;
I really hope someone can help me sort this one out, since accepting and
rejecting connections on a confitional basis is something I really need in
my
server application.
Bye!Sv: Winsock 2 API (på engelska)
CopyMemory Byval VarPtr(InData), Byval lpCallerData, Len(InData)
För att CopyMemory skall använda pkerna. Beror ju givetvis på hur du deklarerat den...
Ber om ursäkt för att jag stör... :O)Sv: Winsock 2 API (på engelska)
Detta påverkar inte resten av problem i vilket fall som. Har jag inte fått ett giltigt lpCallerData värde så kan jag ändå inte kopiera in den i en WSABUF struktur. Mitt problem är som sagt att lpCallerData altud blir noll fast jag skickar med data i mitt WSAConnect anrop