-
1 Attachment(s)
VB6 UniSock: winsock replacement [2008-08-14]
This is my attempt in writing a Winsock class module. The major difference to other implementations is that there are no other files, it is just one class file. By syntax and behavior I've tried to make it imitate the Winsock control when it has made sense. The major syntax differences are the Close event (changed to Closing) and Close method (changed to CloseSocket). I have also adjusted the datatypes, so instead of variants there are more precise datatypes used when appropriate. This allows VB's autocomplete to work.
Unlike other implementations you can use a wide variety of arrays, even string arrays, for both getting and sending data. I've also paid attention in keeping the class efficient & lightweight. There are also small convenience features: many of the methods are now functions that return a boolean value.
The greatest difference to other Winsock implementations is a switch between binary mode and text mode. In text mode you are only able to process text data (ideal for entirely text based conversation, such as IRC). Text mode also disables DataArrival event and enables TextArrival event. Text mode's true power is in that it automatically processes incoming Unicode strings for you, namely UTF-8 and UTF-16. If you expect to receive Unicode data, you don't need to care about it. If you receive ANSI text in TextArrival, you must use StrConv or other method to process the string to displayable form.
I have done testing only with TCP. This means UDP portion of the code is untested. My tests even on TCP side aren't full scale, so if you run into any oddness I'd like to know about it.
A small sample project is included that demonstrates a continuously listening server, a client and a new socket accepted by server when the client connects. The code should be fairly well commented.
-
Re: VB6 UniSock: winsock replacement class
Events
Closing()
Description: Triggered when socket is about to close but has not yet been fully closed.
Connect()
Description: Triggered upon successful connection. Data may now be sent.
ConnectionRequest(RequestID)
Description: Triggered when a remote host is connecting to a listened port.
DataArrival(BytesTotal)
Description: Triggered when data has arrived in binary mode.
Error(Number, Description, sCode, Source, HelpFile, HelpContext, CancelDisplay)
Description: Triggered whenever an internal error occurs.
NOTE: Unlike Winsock control, an error does not prevent operation and you are not required to close the connection.
SendComplete()
Description: Triggered when sending data has finished.
SendProgress(BytesSent, BytesRemaining)
Description: Triggered as sending data progresses.
StatusChange(Status)
Description: Triggered when status changes. However, error status is not received in favor of Error event.
TextArrival(Text, LineChange, ANSI)
Description: Triggered when a line of data has arrived. If text is Unicode, Text can be used directly. If text is ANSI, you must use StrConv or other means to process the text into an usable string.
Methods
Accept(RequestID) Boolean
Description: Accepts a connection request from another UniSock control. The socket must be in a closed state before using this function. Upon successful accept Connect event is fired.
Result: Returns True if the RequestID was valid.
Bind([LocalPort], [LocalIP]) Boolean
Description: Binds socket to currently set local port and ip. These may also be given as parameters. LocalIP can be an IP or a hostname.
Result: Returns True if the IP and port were binded successfully.
CloseSocket() Boolean
Description: Cancels all asynchronous activity and closes the socket.
Result: Returns True if the socket was closed.
Connect([RemoteHost], [RemotePort]) Boolean
Description: If protocol is TCP, begins connection to currently set remote host and port, or given host and/or port. If protocol is UDP, the current local ip and port are bind.
Result: Returns True if the connection could be initialized (TCP) or True if the local ip and port could be bind (UDP).
GetData(Data, [VarType], [MaxLen]) Boolean
Description: Gets current incoming buffer to variable passed to Data. If passed variable is a variant, variable type set into optional VarType will be used. The default datatype is byte array. MaxLen sets the amount of bytes to retrieve. Whole buffer is retrieved if MaxLen is 0 or less, or greater than the buffer size.
Unlike other Winsock control/class implementations, you may use all numeric datatypes and string: Boolean, Byte, Currency, Date, Double, Integer, Long, Single and String. All supported datatypes can be also be passed as arrays. String array separator is automatically detected (CRLF, LF, CR or NullChar). Strings are coerced from ANSI.
Result: Returns True if the buffer was retrieved.
Listen() Boolean
Description: Binds currently set local ip and port if not bind already and starts listening for incoming connections. Upon connection ConnectionRequest event is fired.
Result: Returns True if binding and initializing listening was successful.
PeekData(Data, [VarType], [MaxLen]) Boolean
Description: Identical to GetData, except the data is not removed from the buffer.
SendData(Data) Boolean
Description: Sends the given data to remote host. See GetData for supported datatypes. Strings are coerced to ANSI.
Result: Returns True if inserting data to output buffer was successful.
SendText(Text, [TextFormat]) Boolean
Description: Sends a single line of string data. A line change character determined by LineChange is added to the string. TextFormat determines whether text is converted to UTF-8 or sent as is.
Result: Returns True if inserting data to output buffer was successful.
Properties
BytesReceived() Long
Result: Returns the current size of the incoming data buffer.
LineChange() UniSockLineChange
Description: Returns/sets the bytes that determine line change or array separator. This value is used when sending string arrays and when using SendText.
LocalHostname() String
Description: Returns the current hostname.
LocalIP() String
Description: Returns the current local ip.
LocalPort() Long
Description: Returns/sets the current local port.
Mode() UniSockMode
Description: Returns/sets the mode of the socket. Binary and text modes are supported. In binary mode DataArrival event is triggered. In text mode TextArrival event is triggered.
Protocol() ProtocolConstants
Description: Returns/sets the current protocol. TCP and UDP are supported.
RemoteHost() String
Description: Returns/sets the host to connect to, or returns the host that has been connected to.
RemoteHostIP() String
Description: Returns the remote host IP address as a string.
RemoteIP() Long
Description: Returns the remote host IP address as a 32-bit value.
RemotePort() Long
Description: Returns/sets the remote port to connect to, or port that has been connected to.
RequestHost() String
RequestIP() String
RequestPort() Long
Description: Information available about the remote host that makes a connection request to a listening socket. Use before accepting a connection to determinte whether you wish to accept the request.
SocketHandle() Long
Result: Returns the current open socket handle, or -1.
State() StateConstants
Result: Returns the current connection state of the control.
-
Re: VB6 UniSock: winsock replacement [2008-08-12]
I have now fixed a bug that prevented the class from working in Windows Vista. Apparently this is now the only class solution for VB6 that works in Vista.
-
Re: VB6 UniSock: winsock replacement [2008-08-12]
I can confirm the sample code works in Vista!
I have an unrelated issue, may well be my code as I'm trying to replace my CSocketMaster projects with UniSock.
When my server accepts a connection, the IDE breaks in WndProc() at
Code:
' redirect to new location
PostMessageW m_Request(CStr(wParam)), uMsg, wParam, lParam
with "invalid procedure call or argument"
Ive tried resolving it myself as your sample does work and the problem seems to be in Accept() .. RemoteHost and RemotePort are equal to zero, although it appears the connection has been accepted?
The only difference in my code & the sample code is I'm not passing the RequestID to another control, I only expect a single connection. Any Ideas?
Excellent project though, I'm very gratefull for your work!
-
Re: VB6 UniSock: winsock replacement [2008-08-12]
The problem is that you're still getting old socket's messages, but the old socket is not stored in m_Request array. I'm making some adjustments that should work around this problem (and that will also clean up the memory a bit better than before).
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
The code has been updated.
Edit!
It seems the recent fixes have also made the class perfectly stable, I haven't been able to crash it once.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
yes thats sorted it out! im looking forward to playing around more with this when I have the time, it still seems to crash alot in the IDE tho which is disappointing.
How did you change your code to be vista-compatible? could the same modification perhaps be made to csocketmaster as well?
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
You just have to remove a bit of code that binds a port upon making a TCP connection.
Humm, not Stop button safe anymore... I'll have to take a look into that.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Ah, UDP is something I haven't tested, because I had never actually used it myself anywhere. When making the UDP support I simply copied logic from CSocketMaster's code. I guess I just have to find some simple UDP example and then convert it to UniSock and then start debugging the problem. Not today or tomorrow though: I'm not feeling very good, and tomorrow I'll have a busy day.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
NICE. It works perfectly for my IRC bot (although sometimes I get a GPF, ModName oleaut32, I'm sure it's something I'm doing wrong, bah).
I was just wondering, is it possible to make an array of these or something?
I (stupidly) tried
Code:
Dim WithEvents Sockets(120) As UniSock
Private Sub Form_Load()
Dim x As Long
For x = 0 To 120
Set Sockets(x) = New UniSock
Next
End Sub
but WithEvents doesn't like arrays as far as I can tell.
===========================
Thanks in advance. :)
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Make a class module where you use a single instance WithEvents, then you can have multiple copies of that class module as long as that class module does not use events.
To keep the status somewhat updated, TCP should work pretty fine at the moment, UDP is still not fixed. I got a job so I don't have much time at the moment in my hands, and besides work there are other things going on...
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I've written an HTTP ActiveX control that uses cSocketMaster and I'm trying to replace it with your UniSock class. It compiles fine but when I add the resulting ActiveX control to a project it shuts down the IDE.
I'm still trying to pinpoint the problem but was wondering if you had any ideas.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I probably have to consider using a different method for handling the messages. Unfortunatenaly the IDE safety tricks go over my area of knowledge (in the full depth level) so I can only go ahead guessing what might be wrong. There may be something else that doesn't work well, one thing that I can think about is the method used for detecting whether the class is running under IDE or not (App.LogMode). Switching to a separately made InIDE function might be worth checking out.
That just as initial thoughts without any testing etc.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I'm looking for a way to limit the upload speed, but apparently that can't be done with the Winsock control. Is it possible with this Winsock replacement?
For example, setting SO_SNDBUF or m_SendBufferSize to a smaller size?
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I am not quite sure about speed because it depends on other factors but the buffer size, you can.
Use setsockopt.....I am changing my receive buffer size for UDP transmissions. Take a look at te code below.
lngBuffer = 65535 ' MY receive buffer size
SocketSetOptions m_Socket, SOL_SOCKET, SO_RCVBUF, lngBuffer, 4
if SocketGetOptions(m_Socket, SOL_SOCKET, SO_RCVBUF, lngBuffer, 4) = SOCKET_ERR then
Private_SetState sckerror, "Bind", Err.LastDllError
exit function
else
SocketSetOptions m_Socket, SOL_SOCKET, SO_BROADCAST, lngBuffer, 4
If SocketGetOptions(m_Socket, SOL_SOCKET, SO_MAX_MSG_SIZE, lngBuffer, 4) <> SOCKET_ERR Then
m_ReceiveSize = lngBuffer
m_SendSize = lngBuffer
End If
.....
.....
.....
The changes were made in the Bind function. Instead of SO_RCVBUF use SO_SNDBUF. The minimum applied by the socket is 8192 bytes and the safest min. you should use is 2048.
Regards,
JARP
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I apoligize but the safest buffer size ONLY APPLIES TO my application.
Sorry, for the confussion...
Regards,
JARP
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Thanks.
I set SO_SNDBUF to 8192, 1024, 512, 32 and 1, but unfortunately it makes no difference to the upload speed.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
What is it you want to do? and why?. Your question was if you could change buffer size using Unisock and the answer is yes. As a matter of fact, this issue is not only Unisock it is in general. The speed, as I said is another issue (There are differences between using UDP and TCP/IP in internal timer implementations).
Regards,
JARP
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
We're probably getting offtopic, but I'm looking for a way to limit the upload speed, for example to 50kB/s. The reason is that users keep emailing me every single day to implement that feature. There are hundreds or even thousands of applications that allow you to limit the download/upload speed, like peer-2-peer applications, but nobody out there is able to tell me how it's done.
My question was not if I can change the buffer size (I already knew that was possible), but if for example, changing the buffer size (making it smaller) would allow me to upload slower. It seems the answer is No.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I understand and you are right we probably are off topic so i will give you some quick tips. Check this out http://support.microsoft.com/default...;EN-US;Q233203 and pay careful attention to Qos........I think thats the way to go with some coding effort and then use Unisock for transmission (tcp/ip).
Regards,
JARP
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Thanks, jarp0117, I'll look into that.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
This looks very cool, except I can't get it to do anything. I can see the data coming in on HyperTerminal when set to 'listen' (wait for a call) and I can get data using the regular Winsock control, except that it traps the last 192 bytes of my data and I can't access it until more data comes in. I'm not running all of these apps at the same time, since my client on the other end is asking for one connection. Each spurt of data is separated by 3 or 4 minutes, but I need to parse everything I can receive. Also, it's XML data so there are no CR/LF characters. Winsock wasn't letting my program receive all of the data.
I stripped down your sample project to just the server and servernode parts, then I put in Form_Load:
If Not Server.Bind(5950, "localhost") Then Debug.Print "Server", "Bind failed"
If Not Server.Listen Then Debug.Print "Server", "Listen failed"
If Server.Listen Then Label1 = "Listening"
(I added a label1 for messages). When the program starts, it says "Listening" as expected, but I never get a Server_ConnectionRequest as expected. I can see the requests for the connection coming in using WireShark.
Also, occasionally, when I change a bit of code in Form UniSocketDemo, and then click away from the VB6 IDE, say to an Internet Explorer, the whole IDE crashes.
Any ideas on what I can try. I only need to receive data.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
There is at least one oddness, calling Listen two times:
Code:
If Server.Bind(5950, "localhost") Then
If Server.Listen Then
Label1.Caption = "Listening"
Else
Label1.Caption = "Listen failed"
End If
Else
Label1.Caption = "Bind failed"
End If
If you are displaying a message box it will prevent the events from being processed (under IDE).
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Just to let everyone know, I am now working on a fixed version that will use the same subclassing machine code as CSocketMaster. However, just like this far, I'm rewriting the VB6 code entirely to clean up any clutter.
Doing this as I now need UniSock's special features but I don't want to modify CSocketMaster.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Some updates to let you know something is happening: I've been doing very careful work on analysing how things work and I've kept reading the initialization code over and over again to ensure there are no errors and that the logic should be correct. I've done some things very differently than they're done in CSocketMaster though... for one, I'm still creating a custom window class instead of using a STATIC. At the moment I'm also starting the subclass code immediately upon window creation, which is unlike in CSocketMaster: will see if this can be done or not. If I can't do it like that, well, that is a problem of that time.
I don't like how CSocketMaster separates all the small code portions into a multitude of functions, I've been able to keep things far simpler. I now have one longer code block that reveals all the logic required for initializing everything. This is also true for the reverse, things are cleaned up in a clear order in one place.
Once all this hard work is complete I can mostly paste all the old UniSock code in place and finally start debugging for any issues.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Nice work Merri! I've moved to .Net (Sockets are way better, and there is a winsock lookalike using sockets), but when I do vb6 projects (nostalgia rules), I will def. use this!
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Some progress reports. I have now rewritten the subclasser to fit UniSock. The good news is that the class does not crash IDE even when pausing or stopping IDE and thus the machine code is working as it should. The bad news is that there is some bug somewhere that corrupts a few values that I read from memory and I'm not going to figure it out in the next few hours, leaving that for tomor... err... later. The class is still fully unusable at the moment.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Its great to know UniSock is progressing Merri, Keep up the good work!
Any chance of an update? :bigyello:
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
The last time I've checked your's doesn't support UDP, what about integrating it? :)
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Yup, this can be read about in earlier posts; to continue with this project I'd need many hours of continuous spare time which I haven't had in a good while.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
to use UDP
declare in form header:
Private WithEvents Client As UniSock' ---it already shoud be there
in Form_Load event:
Private Sub Form_Load()
Set Client = New UniSock
Client.Protocol = sckUDPProtocol
Client.Connect 0, 3040' to connect remote broadcast address 255.255.255.255 and use port 3040(netfinder)
in UniSock.cls needs change:
1)in Connect event after
SocketSetOptions m_Socket, SOL_SOCKET, SO_BROADCAST, lngBuffer, 4
'-----------------------------
m_RemoteHost = -1'--add this line to use broadcast address
2)in Private_Bind after:
m_LocalPortBind = lngLocalPort
'-------------------------------
Private_SetState sckOpen'----add this line to proceed
3)in Private_Message uncomment after:
If lngRemoteIP = INADDR_NONE Then
' resolve IP of hostname
'------------------------------
' lngResult = SocketGetHostByName(m_RemoteHost)
' If lngResult Then
' ' get the resolved IP
' RtlMoveMemory udtHostent, ByVal m_HostentPointer, Len(udtHostent)
' GetMem4 udtHostent.hAddrList, lngIPPtr
' GetMem4 lngIPPtr, lngRemoteIP
' Else
' Private_SetState sckError, "Private_Message", WSAGetLastError
' End If
End If
'cose udp not need to resolve remoteIP-- much quicker this way
4) i dont now why in my case XP_pro i get error message to
GetData = (SocketReceiveFrom--- i changed it to
GetData = (SocketReceive(m_Socket, bytArray(0), MaxLen, lngFlags) <> SOCKET_ERR)
as in TCP -get_data-- in my 'Case vbByte' procedure in 'get_data' rutine
5) to read out data in form 'Private Sub Client_DataArrival(ByVal BytesTotal As Long)':
i used this way to read out data:
Dim byteData() As Byte
Client.GetData byteData, vbByte, 4096
Debug.Print StrConv(byteData, vbUnicode)
that's it
I Hope this comment helps anybody to use this class with UDP
great job enyway- i waited this kind of class for a long time and find this a very useful in vb6
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I'm having a small problem with the Unisock, because for some reaon it only transfers the first 8 KB of each file or page I send, and disconnects itself without sending the entire files.
Here's the current debug for a file request and send process, notice I use spServer to listen to requests and usServidor to send the data back:
>>> spServer_ConnectionRequest (Set usServidor = New UniSock; usServidor.Accept RequestID)
>>> usServidor_StatusChange: 7 (Connected)
>>> usServidor_Connect
>>> GET /files/myfile.png
>>> usServidor_SendProgress BytesSent=8192 BytesRemaining=125638
>>> usServidor_StatusChange: 8 (Closing)
>>> usServidor_StatusChange: 0 (Closed)
This issue is driving me mad, only contents smaller than 8 KB are entrirely transferred, bigger files never arrive completely to the client side. :(
Also, how do I create an array of Unisocks so I can attend multiple requests at once? If someone can clarify Merri's explanation when he said...
Quote:
Make a class module where you use a single instance WithEvents, then you can have multiple copies of that class module as long as that class module does not use events.
.. I will appreciate it. Exactly how do I create "multiple copies of that class module" dinamically at run time? I don't know how many requests may arrive at the same time, so I can predict how many sockets will I need simultaneously. Thanks in advance
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
coud you post me code you running
propably you sendsocket with closesocket command
i running UniSock_2008-08-14.zip and all seems OK
'--------
ofcouse 'RaiseEvent SendProgress' event is different of winsock events
just replace
'RaiseEvent SendProgress(lngPos, m_SendBufferSize)'
with
'RaiseEvent SendProgress(m_SendSize, m_SendBufferSize - lngPos)'
and
'RaiseEvent SendProgress(m_SendBufferSize, 0)'
with
'RaiseEvent SendProgress(m_SendBufferSize - lngPos, 0)'
'-----------
seems that vesa is automatically reads sended bytes and reports instead of bytessent=totalsend, bytesremaining=totalBytesToSend
ingvar
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
The subclassing thunk used in this project is, unfortunatenaly, not fit for Winsock use. This causes problems especially when multiple classes are used. The thunk should be replaced with the one from CSocketMaster and other code changes should be done accordingly, but I haven't had the interest (vs. time) to do this.
As the class is now it is, at times, unstable as the thunk does not always properly deal with unloading a socket.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
to Inuya5ha
also i forget - seems that you need compile to P-Code
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Due to "lately" getting a lot of interest in this project I'm now doing some research on getting the class working properly. The hard part is that as I have to use CSocketMaster's ASM thunk (because it is known to work even if the VB code is awful at parts) I'm a bit challenged in converting that code to a class only use. CSocketMaster uses a module and a class together.
To make my life easier I've been gathering up some documentation to work with:
Code:
CSocketMaster's ASM thunk
XX | 00010203 04050607 08090A0B 0C0D0E0F
---| -------- -------- -------- --------
00 | 58505055 89E55753 515231C0 EB0EE8xx 0F EbMode
10 | xxx01x83 F8027422 85C07425 8B45103D
20 | 00080000 74433D01 08000074 5BE82000
30 | 00005A59 5B5FC9C2 1400E813 000000EB
40 | F168xxxx x02x6AFC FF750CE8 xxxxx03x 42 Previous WndProc 4C SetWindowLong
50 | EBE0FF75 18FF7514 FF7510FF 750C68xx 5F Previous WndProc
60 | xxx04xE8 xxxxx05x C3BBxxxx x06x8B45 64 CallWindowProc 6A MsgCountA
70 | 14BFxxxx x07x89D9 F2AF75B6 29CB4B8B 72 MsgTableA1
80 | 1C9Dxxxx x08xEB1D BBxxxxx0 9x8B4514 82 MsgTableA2 89 MsgCountB
90 | BFxxxxx0 Ax89D9F2 AF759729 CB4B8B1C 91 MsgTableB1
A0 | 9Dxxxxx0 Bx895D08 8B1B8B5B 1C89D85A A1 MsgTableB2
B0 | 595B5FC9 FFE0
= 182 bytes
# Decimal position
00 12 JMP [EB0E] -> NOP NOP [9090] (to enable IDE breakpoint check within IDE)
01 15 EbMode
02 66 Previous WndProc
03 76 SetWindowLongA
04 95 Previous WndProc
05 100 CallWindowProc
06 106 MsgCountA
07 114 MsgTableA1 (Asynchronous handle)
08 130 MsgTableA2 (Object pointer = class)
09 137 MsgCountB
10 145 MsgTableB1 (Socket handle)
11 161 MsgTableB2 (Object pointer = class)
CSocketMaster initialization:
1) InitiateProcesses (increase socket counter, in module)
2) Once: Subclass_Initialize (ASM thunk, in module)
3) Once: InitiateService (Winsock, in module)
1) CSocketMaster creates a message window when connecting the first time.
2) There is only one message window for all sockets.
CSocketMaster termination:
1) CleanResolutionSystem (in class)
2) DestroySocket (in class)
3) FinalizeProcesses (decrease socket counter, in module)
4) Once: Subclass_Terminate (end subclass, free memory, in module)
5) Once: Subclass_UnSubclass (restore original WndProc)
' ASM thunk from string to Currency array
Option Explicit
Private Declare Sub RtlMoveMemory Lib "ntdll" (Destination As Long, Source As Long, ByVal Length As Long)
Private Sub Form_Load()
Dim strHex As String, strASM As String * 92
Dim curData(20) As Currency
Dim lngA As Long
strHex = "5850505589E55753515231C0EB0EE8xxxxxxxx83F802742285C074258B45103D0008000074433D01080000745BE8200000005A595B5FC9C21400E813000000EBF168xxxxxxxx6AFCFF750CE8xxxxxxxxEBE0FF7518FF7514FF7510FF750C68xxxxxxxxE8xxxxxxxxC3BBxxxxxxxx8B4514BFxxxxxxxx89D9F2AF75B629CB4B8B1C9DxxxxxxxxEB1DBBxxxxxxxx8B4514BFxxxxxxxx89D9F2AF759729CB4B8B1C9Dxxxxxxxx895D088B1B8B5B1C89D85A595B5FC9FFE0"
For lngA = 1 To 182
MidB$(strASM, lngA, 1) = ChrB$(Val("&H" & Mid$(strHex, lngA * 2 - 1, 2)))
Next lngA
RtlMoveMemory ByVal VarPtr(curData(0)), ByVal StrPtr(strASM), 182
For lngA = 0 To 20
Debug.Print "curASM(" & lngA & ") = " & Format$(curData(lngA), "0\.0000\@")
Next
End Sub
' resulting array
curASM(0) = 60055210061.2645@
curASM(1) = 653186003.0143@
curASM(2) = 24826125609.6095@
curASM(3) = 44000932998.7215@
curASM(4) = 893017331.1255@
curASM(5) = 92626787.4057@
curASM(6) = -44108895140.8696@
curASM(7) = -15132094744.6252@
curASM(8) = -2583940286.2036@
curASM(9) = 38.9313@
curASM(10) = 14743649335.5771@
curASM(11) = 292870985.0788@
curASM(12) = 38.9231@
curASM(13) = 50110990103.7986@
curASM(14) = -27716840956.6978@
curASM(15) = -84094044991.6901@
curASM(16) = 21558168466.2695@
curASM(17) = 14607264862.6786@
curASM(18) = -9475756134.9177@
curASM(19) = 20568209907.7300@
curASM(20) = 6027885582.3052@
Update!
I've done some good progress, but still far away from anything releasable. A lot of to be done is just adjusting old UniSock code to the new code based on CSocketMaster's ASM thunk, but there are also some bigger changes to be done (such as fixing Accept).
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Couple questions, I don't know if they have been answered. Can this be used over WAN? Also does the bind command set the remote host, a local host, or just a host in general? I wrote a winsock app, and i'm trying to convert all of it to unisock so I can take it with me. It's a chat program among other things.
Do the server/client have to be in the same project? Also what is servernode for?
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Use the Connect event. Do not wait in a loop. Also, any continuous DoEvents is likely to break events, ie. by using DoEvents you may actually block the Winsock messages to the UniSock class.
The current UniSock version is still a bit broken; I don't know when I have the fixed, hopefully 100% stable version out, so many things going on in my life atm.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I am trying to make a function like the following:
Code:
Public Function Request(ByRef Output As String, ReqType As String, URL As String, Optional Referer As String = vbNullString) As Boolean
and call it like:
Code:
Dim HTML As String
Request HTML, "GET", "http://www.google.com/"
MsgBox HTML, , "Google's HTML"
And I figured the best way to write that function is with a loop.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
You have to make things event based. So this is how things should work:- Request function is called. This returns True if success on starting a connection attempt. Request string is stored so that it can be accessed from any local function.
- Upon connection Connect event fires. The request string is sent.
- DataArrival event fires. It may fire multiple times for a single request, thus buffering is required. Data moves over the Internet in packets that are limited in size, this is why data may be split in multiple responses.
- Once all data is received, you may call a custom procedure to bring up the message box. You can also close the connection.
Error event is likely to cancel the request.
If you want to simplify things and you only need to download files, you can also check out UserControl's asynchronous download features. However, you still have to deal with events. Events are how VB6 works.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I know that the looping method will work with Winsock. (See attachment here: http://www.vbforums.com/attachment.p...1&d=1199419733)
And I can't use a API or anything else to simply download the files... I need to store the cookies and such. It also needs to be as fast as possible, hence why I'm using Winsock (slow to write & open a file)
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
I have to recommend staying with the Winsock control. As far as I know DoEvents causes problems with anything in VB6 where VB code processes Windows window messages, thus you can't get that done with UniSock the way you want. For example if you add DoEvents to code executed by UniSock you'll get an instant crash (if I recall correctly).
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Same thing will happen with cSocketMaster I assume?
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
UniSock's current version uses SelfCallback ASM thunk and creates a custom message window, which means all window messages are sent directly to VB6 code.
CSocketMaster instead creates a STATIC window for messages and then subclasses this with a bit more specialized ASM thunk. I haven't tested whether this makes a difference with DoEvents; but I know the current UniSock implementation is more vulnerable to problems. This is why I've been converting CSocketMaster's ASM thunk for UniSock, but I still have a lot of work to do to get it all fully working. At the moment the code is able to create a single message window for all UniSock classes and subclass it for each and that part is stable, but all the other code is not adjusted yet.
If you try CSocketMaster you should have a look at Vista issue and make sure you have a Vista/Windows 7 compatible version of it. There is also criticism to CSocketMaster over the forums/web which you may wish to search for to know what issues it has.
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
CSocketMaster worked fine for me. Thanks though. I'll keep UniSock saved :D
-
Re: VB6 UniSock: winsock replacement [2008-08-14]
Hi All,
I know this very old thread but still have a question :(
Can i send the Unicode Data the the server?
Im using the UniText control written by marry.
Code:
Private Sub WS_Connect()
MsgBox "Unisock Connected " & WS.State
Dim Url As String
Dim StrTh As String
StrTh = "GET " & "http://localhost/page.php?name=" & Text1.Text & "&email=" & Text2.Text & "&msg=" & UniText1.Text & vbCrLf
MsgBox StrTh
StrTh = StrTh & "HTTP/1.0" & vbCrLf
StrTh = StrTh & "Accept: */*" & vbCrLf
StrTh = StrTh & "Accept: text/html" & vbCrLf & vbCrLf
StrTh = StrTh & "Content-Type: application/x-www-form-urlencoded" & vbCrLf
WS.SendData StrTh
MsgBox WS.State
End Sub