http://www.freebasic.net/forum/viewtopic.php?t=2058
NetSocket, NetBind, NetListen, NetAccept, NetConnect, NetWrite, NetRead, NetSendString, NetReciveString, NetClose, NetGetHostByName, NetGetHostByAddr ...
The only one difrent is that a Windows programmer must use WSAStartup and WSACleanup.
Now it is simple to use the same code for Linux and Windows.
In Linux i use the name "net.bi" and under Windows "netwin.bi"
netwin.bi
Code: Select all
' netwin.bi by D.J.Peters (Joshy)
' Source: http://freebasic.net/forum
#define build_addr(a,b,c,d) cuint((cuint(d) shl 24) or (cuint(c) shl 16) or (cuint(b) shl 8) or cuint(a))
#define build_port(p) cshort( lobyte(p) * 256 or hibyte(p))
Enum ADDR_FAMILY
AF_UNSPEC = 0 ' Unspecified.
AF_UNIX = 1 ' Local to host (pipes and file-domain).
AF_INET = 2 ' IP protocol family.
AF_IMPLINK = 3
AF_PUP = 4
AF_CHAOS = 5
AF_IPX = 6 ' Novell Internet Protocol.
AF_OSI_ISO = 7
AF_ECMA = 8
AF_DATAKIT = 9
AF_CCITT = 10
AF_SNA = 11
AF_DECnet = 12 ' Reserved for DECnet project.
AF_DLI = 13
AF_LAT = 14
AF_HYLINK = 15
AF_APPLETALK = 16 ' Appletalk DDP.
AF_NETBIOS = 17
AF_VOICEVIEW = 18
AF_FIREFOX = 19
AF_UNKNOWN1 = 20
AF_BAN = 21
AF_ATM = 22
AF_INET6 = 23
AF_CLUSTER = 24
AF_12844 = 25
AF_MAX = 26
End Enum
enum SOCKET_TYPES
SOCK_STREAM = 1
SOCK_DGRAM = 2
SOCK_RAW = 3
SOCK_RDM = 4
SOCK_SEQPACKET = 5
end enum
Enum SOCKET_PROTOCOLS
IPPROTO_IP = 0
IPPROTO_ICMP = 1
IPPROTO_IGMP = 2
IPPROTO_GGP = 3
IPPROTO_TCP = 6
IPPROTO_PUP = 12
IPPROTO_UDP = 17
IPPROTO_IDP = 22
IPPROTO_ND = 77
IPPROTO_RAW = 255
IPPROTO_MAX = 256
End Enum
' Maximum queue length specifiable by listen.
Const SOMAXCONN as uinteger = &H7FFFFFFF
' Address to accept any incoming messages.
const INADDR_ANY as uinteger = &H00000000
' Address to send to all hosts.
const INADDR_BROADCAST as uinteger = &Hffffffff
' Address indicating an error return.
const INADDR_NONE as uinteger = &Hffffffff
Const SOCKET_ERROR = 1
Const INVALID_SOCKET = -1
Enum WSAVERSIONS
VERSION_11 = &H0101
VERSION_22 = &H0202
End Enum
Type WSAData
wVersion As short
wHighVersion As short
szDescription As String * 256 '!!!
szSystemStatus As String * 256 '!!!
iMaxSockets As ushort
iMaxUdpDg As ushort
lpVendorInfo As any ptr
End Type
type HOSTENT field=1
h_name as zstring ptr ' lpString offical name of host
h_aliases as zstring ptr ptr ' lplpString alias list
h_addrtype as ushort ' host address type
h_length as ushort ' length of address
union
h_addr_list as zstring ptr ptr ' lplpString list of addresses from nameserver
h_addr_ip_list as uinteger ptr ptr
end union
end type
#define h_addr h_addr_list[0]
Type servent
s_name As integer
s_aliases As integer
s_port As short
s_proto As integer
End Type
Type protoent
p_name As String 'Official name of the protocol
p_aliases As integer 'Null-terminated array of alternate names
p_proto As integer 'Protocol number, in host byte order
End Type
type SOCKADDR field = 1
sin_family as short
sin_port as short
sin_addr as uinteger
sin_dummy1 as integer
sin_dummy2 as integer
end type
type SOCKADDR_IN as SOCKADDR
type FDSOCKET as integer
Type timeval
tv_sec As integer 'seconds
tv_usec As integer 'and microseconds
End Type
Const FD_SETSIZE = 64
Type fd_set
fd_count As integer '// how many are SET?
fd_array(1 To FD_SETSIZE) As integer '// an array of SOCKETs
End Type
Declare Function WSAGetLastError Lib "ws2_32.dll" alias "WSAGetLastError" () as integer
Declare Function WSAStartup Lib "ws2_32.dll" alias "WSAStartup" ( _
ByVal Version As WSAVERSIONS, _
byval lpData As WSAData ptr) As integer
Declare Function WSACleanup Lib "ws2_32.dll" alias "WSACleanup" () As integer
Declare Function NetGetHostByAddr Lib "ws2_32.dll" alias "gethostbyaddr" ( _
byval lpAddr As uinteger, _
ByVal addr_len As integer, _
ByVal addr_type As integer) As integer
Declare Function NetGetHostByName Lib "ws2_32.dll" alias "gethostbyname" ( _
ByVal host_name As String) As HOSTENT ptr
Declare Function NetGetHostname Lib "ws2_32.dll" alias "gethostname" ( _
ByVal host_name As String, _
ByVal namelen As integer) As integer
Declare Function NetGetServerByName Lib "ws2_32.dll" alias "getservbyname" ( _
ByVal serv_name As String, _
ByVal proto As String) As integer
Declare Function getprotobynumber Lib "ws2_32.dll" ( _
ByVal proto As integer) As integer
Declare Function getprotobyname Lib "ws2_32.dll" ( _
ByVal proto_name As String) As integer
Declare Function getservbyport Lib "ws2_32.dll" ( _
ByVal port As short, _
ByVal proto As integer) As integer
Declare Function NetInet_Addr Lib "ws2_32.dll" alias "inet_addr" ( _
ByRef cp As zstring ptr) As integer
Declare Function NetInet_ntoa Lib "ws2_32.dll" alias "inet_ntoa" ( _
ByVal inn As uinteger) As zstring ptr
Declare Function htons Lib "ws2_32.dll" alias "htons" ( _
ByVal HostValue As short) As short
Declare Function htonl Lib "ws2_32.dll" alias "htonl" ( _
ByVal HostValue As integer) As integer
Declare Function ntohl Lib "ws2_32.dll" alias "ntohl" ( _
ByVal NetValue As integer) As integer
Declare Function ntohs Lib "ws2_32.dll" alias "ntohs" ( _
ByVal NetValue As short) As short
Declare Function NetSocket Lib "ws2_32.dll" alias "socket" ( _
ByVal AF As ADDR_FAMILY, _
ByVal ST As SOCKET_TYPES, _
ByVal Protocol As SOCKET_PROTOCOLS=0) As integer
Declare Function NetClose Lib "ws2_32.dll" alias "closesocket" ( _
ByVal hSocket As FDSOCKET) As integer
Declare Function NetConnect Lib "ws2_32.dll" alias "connect"( _
ByVal hSocket As FDSOCKET, _
ByVal lpAddr As sockaddr_in ptr, _
ByVal AddrSize As integer=sizeof(sockaddr_in)) As integer
Declare Function NetGetSockName Lib "ws2_32.dll" alias "getsockname" ( _
ByVal hSocket As FDSOCKET, _
ByVal lpAddr As sockaddr_in ptr , _
ByVal lpAddrSize As integer ptr) As integer
Declare Function NetGetPeerName Lib "ws2_32.dll" alias "getpeername" ( _
ByVal hSocket As FDSOCKET, _
ByVal lpAddr As sockaddr_in ptr, _
ByVal lpAddrSize As integer ptr) As integer
Declare Function NetBind Lib "ws2_32.dll" alias "bind" ( _
ByVal hSocket As FDSOCKET, _
ByVal lpAddr As sockaddr_in ptr, _
ByVal lpAddrSize As integer ptr) As integer
Declare Function NetListen Lib "ws2_32.dll" alias "listen" ( _
ByVal hSocket As FDSOCKET, _
ByVal nC As integer=3) As integer
Declare Function NetAccept Lib "ws2_32.dll" alias "accept"( _
ByVal hSocket As FDSOCKET, _
ByVal lpAddr As sockaddr_in ptr, _
ByVal lpAddrSize As integer ptr) As integer
Declare Function NetSelect Lib "ws2_32.dll" alias "select" ( _
ByVal nfds As integer, _
ByRef readfds As Any, _
ByRef writefds As Any, _
ByRef exceptfds As Any, _
ByRef timeout As integer) As integer
Declare Function NetRead Lib "ws2_32.dll" alias "recv" ( _
ByVal hSocket As FDSOCKET, _
ByVal lpBuffer As Any ptr, _
ByVal BufferSize As integer, _
ByVal Flags As integer) As integer
Declare Function NetWrite Lib "ws2_32.dll" alias "send" ( _
ByVal hSocket As FDSOCKET, _
ByVal lpBuffer As Any ptr, _
ByVal BufferSize As integer, _
ByVal Flags As integer) As integer
'helpers if you won't send buffers of bytes
function NetSendString(byval hSocket as FDSOCKET,byval message as string) as integer
dim lpBuffer as ubyte ptr
dim as integer l,i
l=len(message)
if l=0 then return 0
lpBuffer=allocate(l)
for i=0 to l-1
lpBuffer[i]=message[i]
next
function=NetWrite(hSocket,lpBuffer,l,0)
deallocate(lpBuffer)
end function
function NetReciveString(byval hSocket as FDSOCKET,byref message as string) as integer
dim lpBuffer as ubyte ptr
dim as integer l,i
message=""
lpBuffer=allocate(4069)
l=NetRead(hSocket,lpBuffer,4069,0)
if l>0 then
for i=0 to l-1
message=message & chr(lpBuffer[i])
next
end if
deallocate(lpBuffer)
function=l
end function
Declare Function getsockopt Lib "ws2_32.dll" ( _
ByVal hSocket As FDSOCKET, _
ByVal Level As integer, _
ByVal OptName As integer, _
ByVal lpOptValue As Any ptr, _
ByVal lpOptSize As integer ptr) As integer
Const WSABASEERR = 10000
Const WSADESCRIPTION_LEN = 257
Const WSASYS_STATUS_LEN = 129
Const WSAEINTR = (WSABASEERR + 4)
Const WSAEBADF = (WSABASEERR + 9)
Const WSAEACCES = (WSABASEERR + 13)
Const WSAEFAULT = (WSABASEERR + 14)
Const WSAEINVAL = (WSABASEERR + 22)
Const WSAEMFILE = (WSABASEERR + 24)
Const WSAEWOULDBLOCK = (WSABASEERR + 35)
Const WSAEINPROGRESS = (WSABASEERR + 36)
Const WSAEALREADY = (WSABASEERR + 37)
Const WSAENOTSOCK = (WSABASEERR + 38)
Const WSAEDESTADDRREQ = (WSABASEERR + 39)
Const WSAEMSGSIZE = (WSABASEERR + 40)
Const WSAEPROTOTYPE = (WSABASEERR + 41)
Const WSAENOPROTOOPT = (WSABASEERR + 42)
Const WSAEPROTONOSUPPORT = (WSABASEERR + 43)
Const WSAESOCKTNOSUPPORT = (WSABASEERR + 44)
Const WSAEOPNOTSUPP = (WSABASEERR + 45)
Const WSAEPFNOSUPPORT = (WSABASEERR + 46)
Const WSAEAFNOSUPPORT = (WSABASEERR + 47)
Const WSAEADDRINUSE = (WSABASEERR + 48)
Const WSAEADDRNOTAVAIL = (WSABASEERR + 49)
Const WSAENETDOWN = (WSABASEERR + 50)
Const WSAENETUNREACH = (WSABASEERR + 51)
Const WSAENETRESET = (WSABASEERR + 52)
Const WSAECONNABORTED = (WSABASEERR + 53)
Const WSAECONNRESET = (WSABASEERR + 54)
Const WSAENOBUFS = (WSABASEERR + 55)
Const WSAEISCONN = (WSABASEERR + 56)
Const WSAENOTCONN = (WSABASEERR + 57)
Const WSAESHUTDOWN = (WSABASEERR + 58)
Const WSAETOOMANYREFS = (WSABASEERR + 59)
Const WSAETIMEDOUT = (WSABASEERR + 60)
Const WSAECONNREFUSED = (WSABASEERR + 61)
Const WSAELOOP = (WSABASEERR + 62)
Const WSAENAMETOOinteger = (WSABASEERR + 63)
Const WSAEHOSTDOWN = (WSABASEERR + 64)
Const WSAEHOSTUNREACH = (WSABASEERR + 65)
Const WSAENOTEMPTY = (WSABASEERR + 66)
Const WSAEPROCLIM = (WSABASEERR + 67)
Const WSAEUSERS = (WSABASEERR + 68)
Const WSAEDQUOT = (WSABASEERR + 69)
Const WSAESTALE = (WSABASEERR + 70)
Const WSAEREMOTE = (WSABASEERR + 71)
Const WSASYSNOTREADY = (WSABASEERR + 91)
Const WSAVERNOTSUPPORTED = (WSABASEERR + 92)
Const WSANOTINITIALISED = (WSABASEERR + 93)
Const WSAEDISCON = (WSABASEERR + 101)
Const WSAENOMORE = (WSABASEERR + 102)
Const WSAECANCELLED = (WSABASEERR + 103)
Const WSAEINVALIDPROCTABLE = (WSABASEERR + 104)
Const WSAEINVALIDPROVIDER = (WSABASEERR + 105)
Const WSAEPROVIDERFAILEDINIT = (WSABASEERR + 106)
Const WSASYSCALLFAILURE = (WSABASEERR + 107)
Const WSASERVICE_NOT_FOUND = (WSABASEERR + 108)
Const WSATYPE_NOT_FOUND = (WSABASEERR + 109)
Const WSA_E_NO_MORE = (WSABASEERR + 110)
Const WSA_E_CANCELLED = (WSABASEERR + 111)
Const WSAEREFUSED = (WSABASEERR + 112)
Const WSAHOST_NOT_FOUND = (WSABASEERR +1001)
Const WSATRY_AGAIN = (WSABASEERR +1002)
Const WSANO_RECOVERY = (WSABASEERR +1003)
Const WSANO_DATA = (WSABASEERR +1004)
Function GetErrorString(ByVal ErrCode As integer) As String
Dim ret As String
Select Case ErrCode
Case WSAEACCES :ret = "Permission denied."
Case WSAEADDRINUSE :ret = "Address already in use."
Case WSAEADDRNOTAVAIL :ret = "Cannot assign requested address."
Case WSAEAFNOSUPPORT :ret = "Address family not supported by protocol family."
Case WSAEALREADY :ret = "Operation already in progress."
Case WSAECONNABORTED :ret = "Software caused connection abort."
Case WSAECONNREFUSED :ret = "Connection refused."
Case WSAECONNRESET :ret = "Connection reset by peer."
Case WSAEDESTADDRREQ :ret = "Destination address required."
Case WSAEFAULT :ret = "Bad address."
Case WSAEHOSTDOWN :ret = "Host is down."
Case WSAEHOSTUNREACH :ret = "No route to host."
Case WSAEINPROGRESS :ret = "Operation now in progress."
Case WSAEINTR :ret = "Interrupted function call."
Case WSAEINVAL :ret = "Invalid argument."
Case WSAEISCONN :ret = "Socket is already connected."
Case WSAEMFILE :ret = "Too many open files."
Case WSAEMSGSIZE :ret = "Message too integer."
Case WSAENETDOWN :ret = "Network is down."
Case WSAENETRESET :ret = "Network dropped connection on reset."
Case WSAENETUNREACH :ret = "Network is unreachable."
Case WSAENOBUFS :ret = "No buffer space available."
Case WSAENOPROTOOPT :ret = "Bad protocol option."
Case WSAENOTCONN :ret = "Socket is not connected."
Case WSAENOTSOCK :ret = "Socket operation on nonsocket."
Case WSAEOPNOTSUPP :ret = "Operation not supported."
Case WSAEPFNOSUPPORT :ret = "Protocol family not supported."
Case WSAEPROCLIM :ret = "Too many processes."
Case WSAEPROTONOSUPPORT:ret = "Protocol not supported."
Case WSAEPROTOTYPE :ret = "Protocol wrong type for socket."
Case WSAESHUTDOWN :ret = "Cannot send after socket shutdown."
Case WSAESOCKTNOSUPPORT:ret = "Socket type not supported."
Case WSAETIMEDOUT :ret = "Connection timed out."
Case WSATYPE_NOT_FOUND :ret = "Class type not found."
Case WSAEWOULDBLOCK :ret = "Resource temporarily unavailable."
Case WSAHOST_NOT_FOUND :ret = "Host not found."
Case WSANOTINITIALISED :ret = "Successful WSAStartup not yet performed."
Case WSANO_DATA :ret = "Valid name, no data record of requested type."
Case WSANO_RECOVERY :ret = "This is a nonrecoverable error."
Case WSASYSCALLFAILURE :ret = "System call failure."
Case WSASYSNOTREADY :ret = "Network subsystem is unavailable."
Case WSATRY_AGAIN :ret = "Nonauthoritative host not found."
Case WSAVERNOTSUPPORTED:ret = "Winsock.dll version out of range."
Case WSAEDISCON :ret = "Graceful shutdown in progress."
Case Else :ret = "Unknown error."
End Select
function = ret
End Function
Code: Select all
#include "netwin.bi"
'server.bas
dim as FDSOCKET hServer,hClient
dim as SOCKADDR serveraddr
dim as SOCKADDR clientaddr
dim as WSADATA wsdata
dim as ubyte ptr lpBuffer
dim as integer addrsize,ret
ret=WSAStartup(VERSION_11,@wsdata)
if ret<>0 then
? "server error: WSAStartup!"
sleep:end -1
end if
with serveraddr
.sin_family =AF_INET
.sin_port =build_port(40000)
.sin_addr =INADDR_ANY
end with
hServer=NetSocket(AF_INET,SOCK_STREAM)
if hServer<0 then
? "server error: socket!"
WSACleanup
sleep:end -1
endif
AddrSize=sizeof(SOCKADDR)
ret=NetBind(hServer,@Serveraddr,@AddrSize)
if ret<0 then
? "server error: bind!"
NetClose(hServer)
WSACleanup
sleep:end -1
end if
ret=NetListen(hServer)
if ret<0 then
? "server error: listen!"
NetClose(hServer)
WSACleanup
sleep:end -1
end if
print "server: wait on client"
hClient=-1
while (hClient<0) and (len(inkey)=0)
hClient=NetAccept(hServer,@clientaddr,@AddrSize)
wend
if hClient>=0 then
print "send message to client"
NetSendString(hClient,"Hello from server...")
else
? "server error: NetSendString!"
end if
if hClient >-1 then NetClose hClient
if hServer >-1 then NetClose hServer
WSACleanup
end 0
Code: Select all
'"client.bas
option explicit
#include "netwin.bi"
'"client.bas"
dim as FDSOCKET hClient,hServer
dim as SOCKADDR ServerAddr
dim as WSADATA wsData
dim as string message
dim as integer ret
with ServerAddr
.sin_family = AF_INET
.sin_port = build_port(40000)
'.sin_addr = build_addr(192,168,0,1)
.sin_addr = build_addr(127,0,0,1) 'localhost
end with
ret=WSAStartup(VERSION_11,@wsData)
if ret<>0 then
? "client error: WSAStartup!"
sleep:end -1
end if
hClient=NetSocket(AF_INET,SOCK_STREAM)
if hClient<0 then
? "client error: socket!"
WSACleanup
sleep:end -1
endif
ret=NetConnect(hClient,@ServerAddr)
if ret<0 then
? "client error: can't connect to server!"
NetClose hClient
WSACleanup
sleep:end -1
end if
print "client: connected"
print "client: try to get a message"
ret=NetReciveString(hClient,message)
if ret<=0 then
print "client: no message from server!"
else
print "client: message from server:->" & message
end if
NetClose hClient
WSACleanup
end