• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 947
  • Last Modified:

Winsock Syntax

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.

http://SQL200:1000/cgi-bin/auth.cgi?ya_da_ya_da_ya

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 "10.0.0.113", "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.

Thanks,
pat
0
mpdillon
Asked:
mpdillon
  • 5
  • 3
1 Solution
 
smidgie82Commented:
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.
0
 
mpdillonAuthor Commented:
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 "10.0.0.113", "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,
pat



0
 
smidgie82Commented:
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("127.0.0.1", 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
sock.Send(enc.GetBytes(Chr(10)))

Dim buf As Byte()
ReDim buf(1024)
sock.Receive (buf)
MsgBox(enc.GetString(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
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
mpdillonAuthor Commented:
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.

http://10.0.0.118:1000/cgi-bin/auth.cgi?UserID=__GATEWAYUSER__;__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?


thanks,
pat
0
 
smidgie82Commented:
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?
0
 
smidgie82Commented:
Just had another thought...  Try also using &vbCrLf instead of & Chr(10) or &vbLf.
0
 
mpdillonAuthor Commented:
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.

pat
0
 
smidgie82Commented:
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: http://www.experts-exchange.com/help.jsp#hs1 and especially this section: http://www.experts-exchange.com/help.jsp#hs5

Thanks a bunch.  Best of luck with your project!

~Dathan
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now