Attached is a User Control for SimpleSock. On the surface, a User Control is easier to use and more compact, but that is not the full story. I have hesitated to produce this control, because it makes a program more difficult to trouble shoot. This post will deal with the User Control itself. To find out more about the SimpleSock Class and it's associated module, see:
https://www.vbforums.com/showthread....B6-Simple-Sock
The User Control contains SimpleSock.cls and modSocket.bas, but we cannot communicate directly with either of these. We must communicate with the User Control. So the User Control instantiates a dummy class which simply forwards the information to these 2 modules and visa versa.
We declare all the "bridge" functions and properties in the control. The idea being that when the user calls a function in the control, we call the cmSocket function. When cmSocket raises an event we raise an event. When the user sets a property we set the cmSocket property. When the user retrieves a property we retrieve the cmSocket property and pass the result to the user.
To create the control, simply compile SIMPLSCK.ocx. Before using the control, I strongly suggest copying it to the \Windows\SysWOW64\ directory (\Windows\System32\ for 32 bit systems) with the rest of the OCX files. To enable the new control, start a new project and select the Components window. Then click on the Browse button, navigate to the "SysWOW64" directory, select the SIMPLSCK.ocx file, and click "OK". That will register the file and add it to the list of components. When you attempt to load the "TestSck" program, you should get a message that the version does not match. That is because the SID that I used to add the control to the test program does not match the one you just created. Let the system update it and save the project.
Using a Control may be convenient and space saving, but it comes at a price. In the IDE, it is a compiled program that you cannot debug directly. Even though there is a Public flag (DbgFlg) in the "modSocket" module, that when set to True will record the Debug.Print output to "socket.log", this is not as convenient as being able to step through the program. That is why I have hesitated making this control until now, and I would strongly suggest using the Class and Module directly in the early stages of program development. For convenience, a variable called "DebugFlag" has been added to the User Control, which sets this flag.
For the next part of the discussion, we need to understand how Winsock works. Winsock does not understand what a record is. It sends and receives data in packets, which generally maxes out around 1,500 bytes (less for WiFi). This is where it gets a little confusing. The actual transmitted packet length is governed by the Ethernet Maximum Transmission Unit (MTU), but the TCP stack can operate at sizes determined by the Maximum Segment Size (MSS). The MSS is 65,535 bytes (64K), but in the case of TLS 1.3, the MSS is 16,384 bytes (16K). Packets can come in at 1,500 bytes, but are not reported to you until the MSS is reached. Your program will generally send and receive data by record. The record length must be handled by you. The record length can be defined in a fixed or variable length header. HTML is a very old standard that uses variable length headers defined by a trailing double CrLf. The test program provided uses HTML.
The "DataArrival" and "EncrDataArrival" routines are re-entrant. That is to say that when one MSS is being processed by your program, Winsock can send more packets. I don't know the internal details of how it is handled, but it appears that a new instance of the subroutine is created for each event, but uses common variables if they have been declared global. If the incoming Winsock buffer is full, it will stop receiving data, but the class incoming buffer can be several times larger than a single record, so while you are processing one record, another one can already be started. This results in the speedy processing of data, but if you halt the program during processing, the class incoming buffer may not contain the expected data. A simple MsgBox falls into this category. In the test program, I have used "frmNotify" instead. It does not halt program execution. You can remove it by clicking on the "X", or hide it by clicking on the form itself (it will reappear 20 seconds later).
The sending of data has the opposite problem. If the Winsock outgoing buffer is full, Winsock will return the WSAEWOULDBLOCK error. It will only take as much data as it can handle. The class buffer is configured to be the same size as the Winsock buffer to minimize transfer trips. Data is added to the end of the class buffer, and Winsock takes data from the front of the class buffer, so you don't have to worry about that part. You only have to be concerned about not overflowing the class buffer. One way to handle this is to use the SendComplete routine. This is not optimal, but it works. When the preceding record has been sent by Winsock, you only load as much data into the class buffer as it can handle. For this purpose, a variable called BufferSize is available from the User Control after a connection has been established.
The Test program supplied is configured like a browser to send HTML requests and receive HTML and binary responses, but it is far from performing like a real browser. To use the control for other purposes, remove the section that sends an HTML request after a connection is established. For secure connections, that code is found in the "HandShake" subroutine.
J.A. Coutts
https://www.vbforums.com/showthread....B6-Simple-Sock
The User Control contains SimpleSock.cls and modSocket.bas, but we cannot communicate directly with either of these. We must communicate with the User Control. So the User Control instantiates a dummy class which simply forwards the information to these 2 modules and visa versa.
Code:
'create an instance of SimpleSock
Set cmSocket = New SimpleSock
To create the control, simply compile SIMPLSCK.ocx. Before using the control, I strongly suggest copying it to the \Windows\SysWOW64\ directory (\Windows\System32\ for 32 bit systems) with the rest of the OCX files. To enable the new control, start a new project and select the Components window. Then click on the Browse button, navigate to the "SysWOW64" directory, select the SIMPLSCK.ocx file, and click "OK". That will register the file and add it to the list of components. When you attempt to load the "TestSck" program, you should get a message that the version does not match. That is because the SID that I used to add the control to the test program does not match the one you just created. Let the system update it and save the project.
Using a Control may be convenient and space saving, but it comes at a price. In the IDE, it is a compiled program that you cannot debug directly. Even though there is a Public flag (DbgFlg) in the "modSocket" module, that when set to True will record the Debug.Print output to "socket.log", this is not as convenient as being able to step through the program. That is why I have hesitated making this control until now, and I would strongly suggest using the Class and Module directly in the early stages of program development. For convenience, a variable called "DebugFlag" has been added to the User Control, which sets this flag.
For the next part of the discussion, we need to understand how Winsock works. Winsock does not understand what a record is. It sends and receives data in packets, which generally maxes out around 1,500 bytes (less for WiFi). This is where it gets a little confusing. The actual transmitted packet length is governed by the Ethernet Maximum Transmission Unit (MTU), but the TCP stack can operate at sizes determined by the Maximum Segment Size (MSS). The MSS is 65,535 bytes (64K), but in the case of TLS 1.3, the MSS is 16,384 bytes (16K). Packets can come in at 1,500 bytes, but are not reported to you until the MSS is reached. Your program will generally send and receive data by record. The record length must be handled by you. The record length can be defined in a fixed or variable length header. HTML is a very old standard that uses variable length headers defined by a trailing double CrLf. The test program provided uses HTML.
The "DataArrival" and "EncrDataArrival" routines are re-entrant. That is to say that when one MSS is being processed by your program, Winsock can send more packets. I don't know the internal details of how it is handled, but it appears that a new instance of the subroutine is created for each event, but uses common variables if they have been declared global. If the incoming Winsock buffer is full, it will stop receiving data, but the class incoming buffer can be several times larger than a single record, so while you are processing one record, another one can already be started. This results in the speedy processing of data, but if you halt the program during processing, the class incoming buffer may not contain the expected data. A simple MsgBox falls into this category. In the test program, I have used "frmNotify" instead. It does not halt program execution. You can remove it by clicking on the "X", or hide it by clicking on the form itself (it will reappear 20 seconds later).
The sending of data has the opposite problem. If the Winsock outgoing buffer is full, Winsock will return the WSAEWOULDBLOCK error. It will only take as much data as it can handle. The class buffer is configured to be the same size as the Winsock buffer to minimize transfer trips. Data is added to the end of the class buffer, and Winsock takes data from the front of the class buffer, so you don't have to worry about that part. You only have to be concerned about not overflowing the class buffer. One way to handle this is to use the SendComplete routine. This is not optimal, but it works. When the preceding record has been sent by Winsock, you only load as much data into the class buffer as it can handle. For this purpose, a variable called BufferSize is available from the User Control after a connection has been established.
The Test program supplied is configured like a browser to send HTML requests and receive HTML and binary responses, but it is far from performing like a real browser. To use the control for other purposes, remove the section that sends an HTML request after a connection is established. For secure connections, that code is found in the "HandShake" subroutine.
J.A. Coutts