Winsock Syntax

Posted on 2006-05-11
Last Modified: 2007-12-19
I am working on a VB 6 app that will communicate with a third party server control. The server control wants inforamtion posted to it in the following format.


sql2000 = local server's name
"ya_da_ya_da_ya" = information to be posted.

I have used the VB winsock control in my app to connect to the server and send the information.

Winsock1.Protocol = sckTCPProtocol
Winsock1.Connect "", "1000"

Winsock1.SendData "ya_da_ya_da_ya"

I have confirmed these three lines of code successfully connect to the server app and send the information. However, since I did not incluce the location of "cgi-bin/auth.cgi", the server does not reply.

How do I connect to the location "cgi-bin/auth.cgi"?
I have tried numerous combinations but they are all just guesses. I do not know how or where to put the "cgi-bin/auth.cgi" in the connect statement.

When I open a browser on the sql2000 machine and type in:
http://localhost:1000/cgi-bin/auth.cgi?ya_da_ya_da_ya, the server responds with the correct information.

Overall, I am trying to create a winsock control that that sends this data and listens for the response.

I am stuck and the project cannot continue until this is resolved.

Question by:mpdillon
    LVL 9

    Expert Comment

    The server only responds to requests in particular formats.  Specifically, you need to send your request in HTTP 1.x compliant form.  Something like the following:

    ' Send the request header
    Winsock1.SendData "GET /cgi-bin/auth.cgi?ya_da_ya_da_ya HTTP/1.1"
    ' Send the host header, in case there are multiple virtual hosts running on the same server
    Winsock1.SendData "Host: SQL200"
    ' Signal the end of our headers
    Winsock1.SendData ""

    I think you'll need to append a linefeed to the end of each string, as well.  The server won't respond until you send two consecutive linefeeds, because that signals the end of the request headers.

    The GET request will do the job in most cases.  But, if there are multiple domains or websites being served from that server, the one you're trying to connect to might not be the default one, so you should specify the Host header as well.  (you can find out by connecting to the server via ip address in your browser instead of using the host name.  If the server responds correctly, you most likely don't need the Host header).

    I recommend you download Firefox and the LiveHTTPHeaders plugin.  Just watch the data going by as you connect to websites.  You probably never realized before exactly what information is required to request the data you want.  It's pretty cool to look at.

    Author Comment

    Thanks, I never would have arrived their on my own.
    I will be out until next Wed so I can't give you any feedback until then. I will send the following 5 lines of code and see what happens.

    Winsock1.Protocol = sckTCPProtocol
    Winsock1.Connect "", "1000"

    Winsock1.SendData "GET /cgi-bin/auth.cgi?ya_da_ya_da_ya HTTP/1.1" & chr(10)
    Winsock1.SendData "Host: SQL200"  & chr(10)
    Winsock1.SendData "" & chr(10)
    If that doesn't work I will strip the chr(10) and try again.

    If it works I will have time to try the Firefox browser.

    Thanks again,

    LVL 9

    Expert Comment

    I'd never done this before from VB (just from C++ and Java), so I decided to give it a shot so I could give you an authoritative answer.  Now, I'm using the System.Net.Sockets.Socket class under .NET, not the Winsock control, but I don't think it'll matter.

    The following lines get me the right results:

    Dim sock As Net.Sockets.Socket
    sock =- New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)
    sock.Connect("", 8080) ' Connect to my local webserver

    ' Don't know about VB before .Net, but under .Net, the default character set is UNICODE.  We don't want that, so we've got to
    ' manually specify the encoding to send our data in.  We want UTF-8
    Dim enc As System.Text.Encoding
    enc = System.Text.Encoding.UTF8()

    sock.Send(enc.GetBytes("GET / HTTP/1.1" & Chr(10)))  ' the request
    ' the Host: header is required for a properly formed request
    ' but the default config for most web servers (running a single site) will accept ANY host
    sock.Send(enc.GetBytes("Host: localhost" & Chr(10)))
    ' and the second consecutive linefeed will end our request

    Dim buf As Byte()
    ReDim buf(1024)
    sock.Receive (buf)

    I mentioned above that the default character encoding for .Net is UNICODE.  Webservers don't like Unicode, so you have to manually convert to UTF-8 encoding.  I don't know if this is the same under VB 6 (and I doubt it is), but it's something to bear in mind.  If the code you have doesn't work (counting the linefeeds, which are necessary), you might have to go digging to see if you have to convert to UTF-8

    Author Comment

    Thanks for doing so much work. I spent time this AM trying different variations of your code. I read Unicode articles, searched for VB6 UTF8 conversion routines but still have not arrived at a solution. I may have inadvertantly not shared as much information as I could have. When I type the following into an IE 6 address line, I get the appropriate response.;__GATEWAY*USER__&ProfileName=JIR&Auth_Transaction_Type=SALE&CardNumber=5000300020003003&ExpDate=12/07&Amount=15.45&Cardpresent=Y&Address=1234+Main+Street&Zip=30328&CustomerCode=123456789&SalesTax=1.23&InvoiceNumber=987654321&CVV2Indicator=1&CVV2Value=123

    The "Ya Da Ya Da Ya" I was referring to is shown(Begins at UserID and ends at 123). I do not think I need to convert it to UTF8 as all the spaces and special characters have been converted. Would you agree?

    My code looked like

        Winsock1.SendData "GET /cgi-bin/auth.cgi?UserID=__GATEWAYUSER__%3B__GATEWAY%2AUSER__&ProfileName=JIR&Auth_Transaction_Type=" & _
        "SALE&CardNumber=5000300020003003&ExpDate=12%2F07&Amount=15.45&Cardpresent=Y&Address=1234+Main+St" & _
        "reet&Zip=30328&CustomerCode=123456789&SalesTax=1.23&InvoiceNumber=987654321&CVV2Indicator=" & _
        "1&CVV2Value=123 HTTP/1.1" & Chr(10) & Chr(10)
        Winsock1.SendData "Host: SQL200" & Chr(10)
        Winsock1.SendData "" & Chr(10)

    Is GET the appropriate function to use or do you think I should try POST?

    An even more basic question would be, I am trying to duplicate the behavior of typing that line into a browser. Is Winsock the correct approach in VB6?

    LVL 9

    Expert Comment

    Yes, GET is definitely the appropriate method to be using.  And your code looks right, except for the double &Chr(10) on the first call to SendData.  Should only be a single.  Might try using & vbLf instead of & Chr(10).  Shouldn't change the functionality, but makes it more readable.

    As to whether Winsock is the correct approach in VB6, I can't really answer you that.  You certainly ought to be able to do it in Winsock, though it may not the The Right Way (tm).

    A couple questions:

    When you execute your code, do you get any errors?
    If not, what data is returned from Winsock1.GetData?
    LVL 9

    Expert Comment

    Just had another thought...  Try also using &vbCrLf instead of & Chr(10) or &vbLf.

    Author Comment

    The end is in sight.
    But before I forget. How do I "Give" you those points? You more than earned them. Is that the Accept button????

    You were right about Get or Post. Get works. Post does not. Their tech support was wrong.

    Late Fri their support sent the output from a successfull connection based on typing the information into the address bar of a browser. Besides the information I was sending, the ya-da-ya-da-ya above, they had sent Accept image/gif..., Accept-Language, Accept-Encoding, User-Agent, etc. I added these statements to my code with the vbCrLf at the end of each send and it worked. Of course, it wasn't quite that simple. Their server sent two responses. I had to ignore the first and process the second. It took a little while to find the second because I was closing the winsock connection as I thought I should so I never new a second response coming. Just something else they neglegted to mention.
    Now I am thinking about wrapping this in an ActiveX EXE without a form so I can access it from VBA. But that is a seperate question altogether.

    Thanks again for all the help. I could not have finished this without your assistance.

    LVL 9

    Accepted Solution

    When you're logged in, beside each of my responses there should be a button that says "accept".  Simply click that to award the points correctly.  For more questions, see the FAQ: and especially this section:

    Thanks a bunch.  Best of luck with your project!


    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Join & Write a Comment

    When pages do not download correctly, and you don't know why, the first thing you do is to look at the HTML source code of that page, but not all the downloaded files appear always clearly. If your source includes a javascript that computes the name…
    Read about why website design really matters in today's demanding market.
    Viewers will get an overview of the benefits and risks of using Bitcoin to accept payments. What Bitcoin is: Legality: Risks: Benefits: Which businesses are best suited?: Other things you should know: How to get started:
    The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

    755 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    18 Experts available now in Live!

    Get 1:1 Help Now