Last active
October 28, 2022 12:52
-
-
Save countingpine/bdbe47e2c92747c470c4367b95edc3da to your computer and use it in GitHub Desktop.
Complete Winsock Server Code, translated to FreeBASIC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
' 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