Things that library support:
- Sending integers
- Sending string
- Sending files and data packets
Things that library will support:
- Linux support
- http protocol (downloading/uploading files)
- ftp protocol
- etc... (give your ideas)
enet.bi
Code: Select all
'' Easy network library
#Include "netwin.bi"
#Define localIP build_addr(127, 0, 0, 1)
#Ifndef maxClients
#Define maxClients 255
#EndIf
Type enet
Private:
server As FDSOCKET
client(maxClients) As FDSOCKET
addrSize As Integer = SizeOf(SOCKADDR)
Declare Function freeClientID() As Integer
Public:
Declare Function isIdFree(id As Integer) As Integer
Declare Function getClient(id As Integer) As FDSOCKET
Declare Function Connect(IP As Integer, port As Integer = 40000) As Integer
Declare Function disconnect(id As Integer) As Integer
Declare Function Close() As Integer
Declare Function startServer(port As Integer = 40000) As Integer
Declare Function Accept() As Integer
Declare Function sendString(msg As String, id As Integer = 0) As Integer
Declare Function getString(id As Integer = 0) As String
Declare Function sendInteger(value As Integer, id As Integer = 0) As Integer
Declare Function getInteger(id As Integer = 0) As Integer
End Type
Function enet.isIdFree(id As Integer) As Integer
If client(id) = 0 Then Return 0
Return -1
End Function
Function enet.getClient(id As Integer) As FDSOCKET
Return client(id)
End Function
Function enet.freeClientID() As Integer
Dim As Integer id
For id=0 To maxClients
If client(id) = 0 Then Return id
Next
Return -1
End Function
Function enet.Connect(IP As Integer, port As Integer = 40000) As Integer
Dim As sockaddr addr
Dim As WSADATA wsdata
With addr
.sin_family = AF_INET
.sin_port = build_port(port)
.sin_addr = IP
End With
If WSAStartup(VERSION_11, @wsdata) <> 0 Then
Return -1
EndIf
client(0) = NetSocket(AF_INET, SOCK_STREAM)
If client(0) < 0 Then
WSACleanup()
Return -2
EndIf
If NetConnect(client(0), @addr) < 0 Then
NetClose(client(0))
WSACleanup()
Return -3
EndIf
Return 0
End Function
Function enet.disconnect(id As Integer) As Integer
If client(id) = 0 Then Return -1
NetClose(client(id))
Return 0
End Function
Function enet.close() As Integer
Dim As Integer id
NetClose(server)
For id=0 To maxClients
If client(id) >= 0 Then NetClose(client(id))
Next
WSACleanup()
Return 0
End Function
Function enet.startServer(port As Integer = 40000) As Integer
Dim As sockaddr addr
Dim As WSADATA wsdata
If WSAStartup(VERSION_11, @wsdata) <> 0 Then
Return -1
EndIf
With addr
.sin_family = AF_INET
.sin_port = build_port(port)
.sin_addr = INADDR_ANY
End With
server = NetSocket(AF_INET, SOCK_STREAM)
If server < 0 Then
Return -2
EndIf
If NetBind(server, @addr, @addrSize) < 0 Then
netclose(server)
WSACleanup()
Return -3
EndIf
If NetListen(server) < 0 Then
NetClose(server)
WSACleanup()
Return -4
EndIf
Return 0
End Function
Function enet.Accept() As Integer
Dim As Integer id = FreeClientID()
client(id) = NetAccept(server, 0, 0)
If client(id) >= 0 Then
Return id
Else
Return -1
EndIf
End Function
Function enet.sendString(msg As String, id As Integer = 0) As Integer
If NetSendString(client(id), msg) < 0 Then Return -1
Return 0
End Function
Function enet.getString(id as Integer = 0) As String
Dim As String msg
If NetReciveString(client(id), msg) > 0 Then
Return msg
EndIf
Return ""
End Function
Function enet.sendInteger(value As Integer, id As Integer = 0) As Integer
If NetWrite(client(id), @value, 4, 0) < 0 Then Return -1
Return 0
End Function
Function enet.getInteger(id As Integer = 0) As Integer
Dim As Integer value
NetRead(client(id), @value, 4, 0)
Return value
End Function
Enum transferTypes
send
RECEIVE
End Enum
Type transfer
Private:
transType As transferTypes
dataPtr As UByte Ptr
dataLen As Integer
currentPacket As Integer
packetSize As Integer
amountPackets As Integer
netPtr As enet Ptr
client As Integer
packet As UByte Ptr
Public:
Declare Function init(transferType As transferTypes, dataPointer As Any Ptr, dataLength As Integer, net As enet Ptr, clientID As Integer = 0, packetSize As Integer = 1024) As Integer
Declare Function sendPacket() As Integer
Declare Function getPacket() As Integer
Declare Function stop() As Integer
Declare Function getDataLength() As Integer
End Type
Function transfer.init(transferType As transferTypes, dataPointer As Any Ptr, dataLength As Integer, net As enet Ptr, clientID As Integer = 0, packetSizeInt As Integer = 1024) As Integer
transType = transferType
dataPtr = dataPointer
dataLen = dataLength
currentPacket = 0
packetSize = packetSizeInt
netPtr = net
client = clientID
packet = Allocate(packetSize)
amountPackets = Int((dataLen-1)/packetSizeInt)
Return 0
End Function
Function transfer.sendPacket() As Integer
If transType = RECEIVE Then Return -1
packet = @dataPtr[currentPacket*packetSize]
If currentPacket < amountPackets Then
NetWrite(netPtr->getClient(client), packet, packetSize, 0)
ElseIf currentPacket = amountPackets Then
NetWrite(netPtr->getClient(client), packet, dataLen-currentPacket*packetSize, 0)
Return 1
EndIf
currentPacket += 1
Return 0
End Function
Function transfer.getPacket() As Integer
If transType = send Then Return -1
Dim As Integer l, i
l = NetRead(netPtr->getClient(client), packet, packetSize, 0)
For i = 0 To l-1
dataPtr[currentPacket*packetSize+i] = packet[i]
Next
If currentPacket = amountPackets Then Return 1
currentPacket += 1
Return 0
End Function
Function transfer.stop() As Integer
currentPacket = 0
Return 0
End Function
Function transfer.getDataLength() As Integer
Return dataLen
End Function
Type file
Private:
length As Integer
Public:
fileData As UByte Ptr
Declare Function getLength() As Integer
Declare Sub setLength(l As Integer)
Declare Sub clearMemory()
Declare Function loadFile(path As String, startPos As Integer = 1, amount As Integer = -1) As Integer
Declare Function saveFile(path As String) As Integer
End Type
Function file.getLength() As Integer
Return length
End Function
Sub file.setLength(l As Integer)
length = l
fileData = Allocate(l)
End Sub
Sub file.clearMemory()
DeAllocate(fileData)
End Sub
Function file.loadFile(path As String, startPos As Integer = 1, amount As Integer = 0) As Integer
Dim As Integer fid = FreeFile()
If Open(path For Binary Access Read As #fid) = 0 Then
If amount < 1 Then amount = Lof(fid)-startPos+1
setLength(amount)
If Get(#fid, startPos, fileData[0], amount) <> 0 Then Return -1
Else
Return -2
EndIf
Return 0
End Function
Function file.saveFile(path As String) As Integer
Dim As Integer fid = FreeFile()
If Open(path For Binary Access Write As #fid) = 0 Then
If Put(#fid, 1, fileData[0], length) <> 0 Then Return -1
Else
Return -2
EndIf
Return 0
End Function
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
Example:
server.bas
Code: Select all
#Include "enet.bi"
Dim As enet net
'' Start server
net.startServer()
'' Accept client connectin
net.accept()
'' Send string to client
net.sendString("Hello, World!")
'' Close server
net.close()
client.bas
Code: Select all
#Include "enet.bi"
Dim As enet net
'' Connect to server (127.0.0.1 for local conection)
net.connect(build_addr(127, 0, 0, 1))
'' Receive string from server and print it
? net.getString()
'' Close client
net.close()
Sleep