Might need fix ups for error constants and getting the errno for linux and osx
SendNetworkDataEX(clientId,*buffer,len,timeout=15000,mutex=0,*error.Integer)
Sends the whole buffer and returns the number of bytes sent or 0 on error
ReceiveNetworkDataEx(clientId,len,timeout=15000,mutex=0,*error.Integer=0)
Returns a pointer to the *buffer or 0 on error
Code: Select all
;-Extra functions
#PB_Network_Error_Fatal = -1
#PB_Network_Error_timeout = -2
#PB_Network_Error_Dropped = -3
#PB_Network_Error_Memory = -4
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
ImportC "-lc"
__errno_location()
EndImport
CompilerEndIf
CompilerEndIf
Procedure NetworkErrorContinue(ID,val=0)
Protected ret,error.l
#WSA_IO_INCOMPLETE = 996
#WSA_IO_PENDING = 997
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
#WSAEINTR = 10004
#WSAEMFILE = 10024
#WSAEWOULDBLOCK = 10035
#WSAEINPROGRESS = 10036
#WSAEALREADY = 10037
CompilerCase #PB_OS_Linux
#WSAEINTR = 4 ; EINTR
#WSAEMFILE = 17 ; ENOFILE
#WSAEWOULDBLOCK = 11 ; Eagain
#WSAEINPROGRESS = 115 ; EINPROGRESS
#WSAEALREADY = 114 ; EALREADY
CompilerCase #PB_OS_MacOS
#WSAEINTR = 4 ; EINTR
#WSAEMFILE = 24 ; EMFILE
#WSAEWOULDBLOCK = 35 ; EWOULDBLOCK = EAGAIN
#WSAEINPROGRESS = 36 ; EINPROGRESS
#WSAEALREADY = 37 ; EALREADY
CompilerEndSelect
#TLS_WANT_POLLIN = -2
#TLS_WANT_POLLOUT = -3
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
error = WSAGetLastError_()
CompilerElse
CompilerIf #PB_Compiler_Backend = #PB_Backend_C
!#include "errno.h"
!extern int errno;
!v_error=errno;
CompilerElse
error = PeekL(__errno_location())
CompilerEndIf
CompilerEndIf
If val = #TLS_WANT_POLLIN
Debug "#TLS_WANT_POLLIN"
ProcedureReturn 1
EndIf
If val = #TLS_WANT_POLLOUT
Debug "#TLS_WANT_POLLOUT"
ProcedureReturn 1
EndIf
Select error
Case 0 ;shouldn't really get a case of 0 it means the errors been reset
ret = 0
Debug "None"
Case #WSAEWOULDBLOCK
ret = 1
Debug "#WSAEWOULDBLOCK"
Case #WSAEINPROGRESS
Debug "#WSAEINPROGRESS"
ret = 1
Case #WSAEALREADY
Debug "#WSAEALREADY"
ret = 1
Case #WSA_IO_INCOMPLETE
Debug "#WSA_IO_INCOMPLETE"
ret =1
Case #WSA_IO_PENDING
Debug "#WSA_IO_PENDING"
ret = 1
Case #WSAEMFILE
ret =1
Debug "#WSAEMFILE"
Default
Debug error
EndSelect
ProcedureReturn ret
EndProcedure
Procedure ReceiveNetworkDataEx(clientId,len,timeout=15000,mutex=0,*error.Integer=0)
Protected result,recived,recvTimeout
If len > 0
Protected *buffer = AllocateMemory(len)
If *buffer
recvTimeout=ElapsedMilliseconds()+timeout
Repeat
If result > 0
*buffer = ReAllocateMemory(*buffer, recived + len)
EndIf
If *buffer
If mutex
Repeat
If TryLockMutex(mutex)
Result = ReceiveNetworkData(clientId,*buffer+recived, len)
If result < 0
If NetworkErrorContinue(clientId,result)
Delay(1)
Else
UnlockMutex(mutex)
FreeMemory(*buffer)
If *error
*error\i = #PB_Network_Error_Fatal
EndIf
ProcedureReturn 0
EndIf
EndIf
UnlockMutex(mutex)
Break
Else
Delay(10)
EndIf
Until ElapsedMilliseconds() > recvTimeout
Else
Result = ReceiveNetworkData(clientId,*buffer+recived, len)
If result < 0
If NetworkErrorContinue(clientId,result)
Delay(1)
Continue
Else
FreeMemory(*buffer)
If *error
*error\i = #PB_Network_Error_Fatal
EndIf
ProcedureReturn 0
EndIf
EndIf
EndIf
If result > 0
recived+result
recvTimeout = ElapsedMilliseconds() + timeout
ElseIf result = 0
FreeMemory(*buffer)
If *error
*error\i = #PB_Network_Error_Dropped
EndIf
ProcedureReturn 0
EndIf
Else
If *error
*error\i = #PB_Network_Error_Memory
EndIf
ProcedureReturn 0
EndIf
If ElapsedMilliseconds() > recvTimeout
FreeMemory(*buffer)
If *error
*error\i = #PB_Network_Error_timeout
EndIf
ProcedureReturn 0
EndIf
Until result <> len
ProcedureReturn *buffer
EndIf
EndIf
EndProcedure
Procedure SendNetworkDataEX(clientId,*buffer,len,timeout=15000,mutex=0,*error.Integer=0)
Protected totalSent,tryLen,sendLen,sendTimeout
sendTimeout = ElapsedMilliseconds() + timeout
Repeat
tryLen = len - totalSent
If tryLen > len
tryLen = len
EndIf
If mutex
Repeat
If TryLockMutex(mutex)
sendLen = SendNetworkData(clientId, *Buffer+totalSent,tryLen)
If sendLen < 0
If NetworkErrorContinue(clientId,sendLen)
Delay(1)
Else
If *error
*error\i = #PB_Network_Error_Fatal
EndIf
UnlockMutex(mutex)
ProcedureReturn 0
EndIf
EndIf
UnlockMutex(mutex)
Break
Else
Delay(10)
EndIf
Until ElapsedMilliseconds() > sendTimeout
Else
sendLen = SendNetworkData(clientId, *Buffer+totalSent,tryLen)
If sendLen < 0
If NetworkErrorContinue(clientId,sendLen)
Delay(1)
Else
If *error
*error\i = #PB_Network_Error_Fatal
EndIf
ProcedureReturn 0
EndIf
EndIf
EndIf
If sendLen > 0
totalSent + sendLen
sendLen = 0
sendTimeout = ElapsedMilliseconds() + timeout
ElseIf sendLen = 0
If *error
*error\i = #PB_Network_Error_Dropped
EndIf
ProcedureReturn 0
EndIf
If ElapsedMilliseconds() > sendTimeout
If *error
*error\i = #PB_Network_Error_timeout
EndIf
ProcedureReturn 0
EndIf
Delay(1)
Until totalSent >= len
ProcedureReturn totalSent
EndProcedure