Skip to content

Instantly share code, notes, and snippets.

@countingpine
Last active October 28, 2022 12:52
Show Gist options
  • Save countingpine/bdbe47e2c92747c470c4367b95edc3da to your computer and use it in GitHub Desktop.
Save countingpine/bdbe47e2c92747c470c4367b95edc3da to your computer and use it in GitHub Desktop.
Complete Winsock Server Code, translated to FreeBASIC
' https://docs.microsoft.com/en-us/windows/desktop/winsock/complete-server-code
#define WIN32_LEAN_AND_MEAN
#include "win/winsock2.bi"
#include "win/ws2tcpip.bi"
const DEFAULT_BUFLEN = 512
const DEFAULT_PORT = 27015
const NEWLINE = !"\n"
function saytext(byval ClientSocket as SOCKET, byref text as const string = !"Hello!" & NEWLINE) as integer
dim as long iSendResult
iSendResult = send(ClientSocket, strptr(text), len(text), 0)
if iSendResult = SOCKET_ERROR then
print "send failed with error: " & WSAGetLastError()
closesocket(ClientSocket)
WSACleanup()
return 1
end if
print "Connection closing..."
return 0
end function
function serveprogram(byval ClientSocket as SOCKET, byref shellcmd as const string) as integer
dim as long iSendResult
dim as string text
open pipe (shellcmd) for input as #1
do until eof(1)
line input #1, text
text &= NEWLINE
iSendResult = send(ClientSocket, strptr(text), len(text), 0)
if iSendResult = SOCKET_ERROR then
print "send failed with error: " & WSAGetLastError()
close #1
closesocket(ClientSocket)
WSACleanup()
return 1
end if
loop
close #1
print "Connection closing..."
return 0
end function
function echoloop(byval ClientSocket as SOCKET) as integer
dim as long iResult, iSendResult
dim as ubyte recvbuf(0 to DEFAULT_BUFLEN - 1)
dim as long recvbuflen = DEFAULT_BUFLEN
'' Receive until the peer shuts down the connection
do
iResult = recv(ClientSocket, @recvbuf(0), recvbuflen, 0)
if iResult then
print "Bytes received: " & iResult
'' Echo the buffer back to the sender
iSendResult = send(ClientSocket, @recvbuf(0), iResult, 0)
if iSendResult = SOCKET_ERROR then
print "send failed with error: " & WSAGetLastError()
closesocket(ClientSocket)
WSACleanup()
return 1
end if
print "Bytes sent: " & iSendResult
elseif iResult = 0 then
print "Connection closing..."
else
print "recv failed with error: " & WSAGetLastError()
closesocket(ClientSocket)
WSACleanup()
return 1
end if
loop while iResult > 0
end function
function socketlisten(byval port as integer = DEFAULT_PORT) as integer
dim as string sPort = str(port)
dim as WSADATA wsaData
dim as long iResult
dim as SOCKET ListenSocket = INVALID_SOCKET
dim as SOCKET ClientSocket = INVALID_SOCKET
dim as addrinfo ptr result = NULL
dim as addrinfo hints
'' Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), @wsaData)
if iResult <> 0 then
print "WSAStartup failed with error: " & iResult
return 1
end if
ZeroMemory(@hints, sizeof(hints))
with hints
.ai_family = AF_INET
.ai_socktype = SOCK_STREAM
.ai_protocol = IPPROTO_TCP
.ai_flags = AI_PASSIVE
end with
'' Resolve the server address and port
iResult = getaddrinfo(NULL, strptr(sPort), @hints, @result)
if iResult <> 0 then
print "getaddrinfo failed with error: " & iResult
WSACleanup()
return 1
end if
'' Create a SOCKET for connecting to server
ListenSocket = socket_(result->ai_family, result->ai_socktype, result->ai_protocol)
if ListenSocket = INVALID_SOCKET then
print "socket failed with error: " & WSAGetLastError()
freeaddrinfo(result)
WSACleanup()
return 1
end if
'' Setup the TCP listening socket
iResult = bind( ListenSocket, result->ai_addr, result->ai_addrlen)
if iResult = SOCKET_ERROR then
print "bind failed with error: " & WSAGetLastError()
freeaddrinfo(result)
WSACleanup()
return 1
end if
freeaddrinfo(result)
iResult = listen(ListenSocket, SOMAXCONN)
if iResult = SOCKET_ERROR then
print "listen failed with error: " & WSAGetLastError()
closesocket(ListenSocket)
WSACleanup()
return 1
end if
'' Accept a client socket
ClientSocket = accept(ListenSocket, NULL, NULL)
if ClientSocket = INVALID_SOCKET then
print "accept failed with error: " & WSAGetLastError()
closesocket(ListenSocket)
WSACleanup()
return 1
end if
'' No longer need server socket
closesocket(ListenSocket)
print "Listening on Port " & sPort
'' Listen and Respond loop
dim as integer ret = echoloop(ClientSocket)
if ret <> 0 then return ret
'' shutdown the connection since we're done
iResult = shutdown(ClientSocket, SD_SEND)
if iResult = SOCKET_ERROR then
print "shutdown failed with error: " & WSAGetLastError()
closesocket(ClientSocket)
WSACleanup()
return 1
end if
'' cleanup
closesocket(ClientSocket)
WSACleanup()
return 0
end function
dim as integer ret
dim as integer port
if __FB_ARGC__ > 1 then port = cint(__FB_ARGV__[1]) else port = DEFAULT_PORT
ret = socketlisten(port)
end (ret)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment