I'd love to learn about Winsock and TCP but I really don't know where to start. Basically I want to jump right into the deep end and write a program, but I doubt I'd get too far with that so hopefully someone could point me in the right direction.

I've done some searching, so far the best code I can find is Iczelion's program which downloads files through http (I believe). However its a big enough program so it's awkard enough to follow. Practically everyting else I've found doesn't use pure winsock api but rather works inside c++ oop or something else and so is very hard to follow.

I imagine programs that work over the net have to be very robust to account for evrything that can and does tend to go wrong, but that make them hard for a beginner to the field.

Would anyone have or know of some completely stripped down examples or good tutorials which I could study first.

Thank you :)
Posted on 2002-04-20 12:27:27 by Eóin
I've done some searching, so far the best code I can find is Iczelion's program which downloads files through http (I believe). However its a big enough program so it's awkard enough to follow. Practically everyting else I've found doesn't use pure winsock api but rather works inside c++ oop or something else and so is very hard to follow.


You can read the winsock 2 reference, it's available at my site. Or if you have the PSDK, read the latest docs.
Another very good resource is the winsock programmer's FAQ here:
http://tangentsoft.net/wskfaq/

The most common questions are answered here.


I imagine programs that work over the net have to be very robust to account for evrything that can and does tend to go wrong, but that make them hard for a beginner to the field.


This is certainly true. When you program an application that uses the internet (or any network), you should assume the data you receive can be *anything*.


Would anyone have or know of some completely stripped down examples or good tutorials which I could study first.

There have been some examples at this board in the networking section. I can send you the source of the my first HTTP file transfer program but it's one of my first programs and not very well written so it might not be a good example.

Thomas
Posted on 2002-04-20 17:14:25 by Thomas
Thank you for that link, it's very helpful. I had already found the reference on your site (a great site by the way), but on its own it was a bit complicated.

However with some more searching I've come across what seem to be two nice guides. If anyone is intrersted they are http://www.hal-pc.org/~johnnie2/winsock.html and http://world.std.com/~jimf/papers/sockets/winsock.html. I'm going to try and work from them for the moment.

Thanks for offering to send me your source code, but it's unlikely I'd be able to make heads nor tails of it at this stage so I'll pass for the moment. If the offer stays open I'll email you.

Thanks agian.
Posted on 2002-04-20 18:15:31 by Eóin
Hmm, I've run into some problems early on. Maybe someone might know what I'm doing wrong. I'm trying to follow the guides I mentioned above, but I can't see what I'm doing different here.

I call gethostbyname with something like "www.google.com". That returns a valid pointer to a hostent structre and I can read the values in it. So then I call socket with AF_INET, SOCK_STREAM & IPPROTO_TCP as parameters. This returns what I imagine is a proper value, ie not 0 or -1 but rather something around 1800 usually.

So then I proceed to fill out a FONT=courier new]sock_addr struct. Now I've run into a bit of inconsistity with the actaul deffinition of this structre, the one I used was
struc sockaddr_in {

.sin_family dw ?
.sin_port dw ?
.sin_addr dd ?
.sin_zero rb 8
}
which is 16 bytes long.

I set
sin_family to AF_INET, (This matches the value in the h_addrtype element of the hostent structre returned by gethostname.

sin_port to the valuse returned by htons called with 80.

sin_addr to the value at the h_addr_list element of the hostent struct.

Then I tried calling connect but it returns -1 ie SOCKET_ERROR. Unfortunatly a subsequent call to WSAGetLastError returns 0 which is no help.

Here is the Fasm code, the red is the values displayed.


invoke gethostbyname,hostname
mov ,eax
mov eax,
invoke SetDlgItemInt,,1002,eax,1 639844

invoke socket,AF_INET,SOCK_STREAM,IPPROTO_TCP
mov ,eax
invoke SetDlgItemInt,,1003,eax,0 1892

mov ,AF_INET
mov eax,
mov eax,
mov ,eax
invoke SetDlgItemInt,,1004,dword ,1 639844

invoke htons,word 80
mov ,ax
movzx eax,
invoke SetDlgItemInt,,1005,eax,1 2

invoke connect,,sain,16
invoke SetDlgItemInt,,1006,eax,-1 -1

invoke WSAGetLastError
invoke SetDlgItemInt,,1007,eax,-1 0
-1

Hopefully I've made sense, if anyone has any ideas I'd be very grateful. Thanks
Posted on 2002-04-20 20:11:33 by Eóin
Have you been to Iczelion's winsock page?:http://spiff.tripnet.se/~iczelion/asmsockguide.html

I am having problems with gethostbyname too.

Here is some of my code, maybe it can help:



mov eax, dword ptr [portServer] ;
mov ecx, dword ptr [portServer+1] ;
and eax, 0FFh ;
and ecx, 0FFh ;
jne _Con ;
sub eax, 30h ;
jmp @F ;
_Con: lea eax, [4*eax][eax] ;
lea eax, [2*eax + ecx - 210h] ;
mov ecx, dword ptr [portServer+2] ;
and ecx, 0FFh ;
je @F ;
lea eax, [4*eax][eax] ;
lea eax, [2*eax + ecx - 30h] ;
mov ecx, dword ptr [portServer+3] ;
and ecx, 0FFh ;
je @F ;
lea eax, [4*eax][eax] ;
lea eax, [2*eax + ecx - 30h] ;
mov ecx, dword ptr [portServer+4] ;
and ecx, 0FFh ;
je @F ;
lea eax, [4*eax][eax] ;
lea eax, [2*eax + ecx - 30h] ;
@@: bswap eax ;
shr eax, 16 ;
mov socketAddress.sin_port, ax ;
mov socketAddress.sin_family, AF_INET ;
;

;
push offset server ;
call inet_addr ;
cmp eax, INADDR_NONE ;
jne @F ;
push offset server ;
call gethostbyname ;
test eax, eax ;
je @F ;
mov eax, dword ptr [eax + 12] ;
mov eax, dword ptr [eax] ;
mov eax, dword ptr [eax] ;
@@: mov socketAddress.sin_addr, eax ;
;

;
GetWinsock: lea ecx, wsaData ;
push ecx ;
push WINSOCK11 ;
call WSAStartup ;
;

;
WinsockSuccess: push IPPROTO_IP ;
push SOCK_STREAM ;
push AF_INET ;
call socket ;
mov dword ptr [hSocket], eax ;
;

;
ServerConnect: lea ecx, socketAddress ;
push sizeof sockaddr_in ;
push ecx ;
push eax ;
call connect ;
test eax, eax ;
jne Done ;
;
Posted on 2002-04-20 22:49:23 by bdjames
Thanks for that link bdjames, it was a great help and I believe I've solved my problem, actually there were two things wrong.

First I was directly moving the h_addr_list value in the hostent structre directly into the sock_addr struct. But that value is a pointer to a pointer to the value I was suppose to be putting into the sock_addr. That explains why the c code for that was so hard to follow.

Secondly, and stupidly I was going by the winsock help says you pass a word value to hotns, actually I should have know you pass a dword.
Posted on 2002-04-21 07:05:41 by Eóin
E?in: htons and htonl basically just swap the bytes in a word or dword. A bswap or ror ax,8 will do as well.
If you are using constant values (eg port 80) you can use these macros as well:

http://www.madwizard.org/snippets/viewSnippet.php?s_ID=4

Thomas
Posted on 2002-04-21 07:10:57 by Thomas