Sockets
You are encouraged to solve this task according to the task description, using any language you may know.
For this exercise a program is open a socket to localhost on port 256 and send the message "hello socket world" before closing the socket.
Catching any exceptions or errors is not required.
Ada
with GNAT.Sockets; use GNAT.Sockets;
procedure Socket_Send is
Client : Socket_Type;
begin
Initialize;
Create_Socket (Socket => Client);
Connect_Socket (Socket => Client,
Server => (Family => Family_Inet,
Addr => Inet_Addr ("127.0.0.1"),
Port => 256));
String'Write (Stream (Client), "hello socket world");
Close_Socket (Client);
end Socket_Send;
Aime
file i, o;
tcpip_connect(i, o, "127.0.0.1", 256, 0);
i.text("hello socket world");
AutoHotkey
modified from script by zed gecko.
Network_Port = 256
Network_Address = 127.0.0.1
NewData := false
DataReceived =
GoSub, Connection_Init
SendData(socket,"hello socket world")
return
Connection_Init:
OnExit, ExitSub
socket := ConnectToAddress(Network_Address, Network_Port)
if socket = -1
ExitApp
Process, Exist
DetectHiddenWindows On
ScriptMainWindowId := WinExist("ahk_class AutoHotkey ahk_pid " . ErrorLevel)
DetectHiddenWindows Off
NotificationMsg = 0x5556
OnMessage(NotificationMsg, "ReceiveData")
FD_READ = 1
FD_CLOSE = 32
if DllCall("Ws2_32\WSAAsyncSelect", "UInt", socket, "UInt", ScriptMainWindowId, "UInt", NotificationMsg, "Int", FD_READ|FD_CLOSE)
{
MsgBox % "WSAAsyncSelect() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
ExitApp
}
return
ConnectToAddress(IPAddress, Port)
{
VarSetCapacity(wsaData, 32)
result := DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData)
if ErrorLevel
{
MsgBox WSAStartup() could not be called due to error %ErrorLevel%. Winsock 2.0 or higher is required.
return -1
}
if result
{
MsgBox % "WSAStartup() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
return -1
}
AF_INET = 2
SOCK_STREAM = 1
IPPROTO_TCP = 6
socket := DllCall("Ws2_32\socket", "Int", AF_INET, "Int", SOCK_STREAM, "Int", IPPROTO_TCP)
if socket = -1
{
MsgBox % "socket() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError")
return -1
}
SizeOfSocketAddress = 16
VarSetCapacity(SocketAddress, SizeOfSocketAddress)
InsertInteger(2, SocketAddress, 0, AF_INET)
InsertInteger(DllCall("Ws2_32\htons", "UShort", Port), SocketAddress, 2, 2)
InsertInteger(DllCall("Ws2_32\inet_addr", "Str", IPAddress), SocketAddress, 4, 4)
if DllCall("Ws2_32\connect", "UInt", socket, "UInt", &SocketAddress, "Int", SizeOfSocketAddress)
{
MsgBox % "connect() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") . "?"
return -1
}
return socket
}
ReceiveData(wParam, lParam)
{
global DataReceived
global NewData
socket := wParam
ReceivedDataSize = 4096
Loop
{
VarSetCapacity(ReceivedData, ReceivedDataSize, 0)
ReceivedDataLength := DllCall("Ws2_32\recv", "UInt", socket, "Str", ReceivedData, "Int", ReceivedDataSize, "Int", 0)
if ReceivedDataLength = 0
ExitApp
if ReceivedDataLength = -1
{
WinsockError := DllCall("Ws2_32\WSAGetLastError")
if WinsockError = 10035
{
DataReceived = %TempDataReceived%
NewData := true
return 1
}
if WinsockError <> 10054
MsgBox % "recv() indicated Winsock error " . WinsockError
ExitApp
}
if (A_Index = 1)
TempDataReceived =
TempDataReceived = %TempDataReceived%%ReceivedData%
}
return 1
}
SendData(wParam,SendData)
{
socket := wParam
SendDataSize := VarSetCapacity(SendData)
SendDataSize += 1
sendret := DllCall("Ws2_32\send", "UInt", socket, "Str", SendData, "Int", SendDatasize, "Int", 0)
}
InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
{
Loop %pSize%
DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}
ReceiveProcedure:
if NewData
GuiControl, , ReceivedText, %DataReceived%
NewData := false
Return
ExitSub:
DllCall("Ws2_32\WSACleanup")
ExitApp
AutoIt
Func _HelloWorldSocket()
TCPStartup()
$Socket = TCPConnect("127.0.0.1", 256)
TCPSend($Socket, "Hello World")
TCPCloseSocket($Socket)
TCPShutdown()
EndFunc
AWK
Note: |&
is gawk's two way pipe operator.
Server:
BEGIN {
s="/inet/tcp/256/0/0"
print strftime() |& s
close(s)
}
Test client:
BEGIN {
s="/inet/tcp/0/localhost/256"
s |& getline
print $0
close(s)
}
BBC BASIC
INSTALL @lib$+"SOCKLIB"
PROC_initsockets
socket% = FN_tcpconnect("localhost", "256")
IF socket% <=0 ERROR 100, "Failed to open socket"
REM Don't use FN_writesocket since an error is expected
msg$ = "hello socket world"
SYS `send`, socket%, !^msg$, LEN(msg$), 0 TO result%
PROC_closesocket(socket%)
PROC_exitsockets
C
With little changes it could work on MS Windows (without Cygwin) too. But I don't know exactly how. I have tested it using nc -l -p 256
.
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
const char *msg = "hello socket world";
int main()
{
int i, sock, len, slen;
struct addrinfo hints, *addrs;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (0 == getaddrinfo("localhost", "256", &hints, &addrs))
{
sock = socket(addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol);
if ( sock >= 0 )
{
if ( connect(sock, addrs->ai_addr, addrs->ai_addrlen) >= 0 )
{
const char *pm = msg;
do
{
len = strlen(pm);
slen = send(sock, pm, len, 0);
pm += slen;
} while ((0 <= slen) && (slen < len));
}
close(sock);
}
freeaddrinfo(addrs);
}
}
C#
using System;
using System.IO;
using System.Net.Sockets;
class Program {
static void Main(string[] args) {
TcpClient tcp = new TcpClient("localhost", 256);
StreamWriter writer = new StreamWriter(tcp.GetStream());
writer.Write("hello socket world");
writer.Flush();
tcp.Close();
}
}
Clean Socket alternative:
using System.Text;
using System.Net.Sockets;
namespace SocketClient
{
class Program
{
static void Main(string[] args)
{
var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect("127.0.0.1", 1000);
sock.Send(Encoding.ASCII.GetBytes("Hell, world!"));
sock.Close();
}
}
}
C++
I have tested it using nc -vlp 4321
.
//compile with g++ main.cpp -lboost_system -pthread
#include <boost/asio.hpp>
int main()
{
boost::asio::io_context io_context;
boost::asio::ip::tcp::socket sock(io_context);
boost::asio::ip::tcp::resolver resolver(io_context);
boost::asio::ip::tcp::resolver::query query("localhost", "4321");
boost::asio::connect(sock, resolver.resolve(query));
boost::asio::write(sock, boost::asio::buffer("Hello world socket\r\n"));
return 0;
}
Cind
var libsocket = @("lib","socket");
// connect
int socket = libsocket.connect("localhost",256);
// send data
{
sheet data = (sheet)"hello socket world";
int datalen = data.size();
int was = libsocket.send(socket,data,0,datalen);
// assuming here that all data has been sent (if not, send them in some loop)
}
// close socket
libsocket.close(socket);
Clojure
(ns socket-example
(:import (java.net Socket)
(java.io PrintWriter)))
(defn send-data [host msg]
(with-open [sock (Socket. host 256)
printer (PrintWriter. (.getOutputStream sock))]
(.println printer msg)))
(send-data "localhost" "hello socket world")
Common Lisp
CL-USER> (usocket:with-client-socket (socket stream "localhost" 256)
(write-line "hello socket world" stream)
(values))
; No value
aurora ~% sudo nc -l -p 256
hello socket world
D
module socket ;
import std.stdio ;
import std.socket ;
version(Win32) {
// For Win32 systems, need to link with ws2_32.lib.
pragma(lib, "ws2_32.lib") ;
}
void main() {
long res;
auto socket = new Socket(AddressFamily.INET, SocketType.STREAM) ;
socket.connect(new InternetAddress("localhost",256)) ;
res = socket.send(cast(void[])"hello socket world") ;
writefln("Socket %d bytes sent.", res) ;
socket.close() ;
}
Delphi
program Sockets;
{$APPTYPE CONSOLE}
uses IdTCPClient;
var
lTCPClient: TIdTCPClient;
begin
lTCPClient := TIdTCPClient.Create(nil);
try
lTCPClient.Host := '127.0.0.1';
lTCPClient.Port := 256;
lTCPClient.Connect;
lTCPClient.IOHandler.WriteLn('hello socket world');
finally
lTCPClient.Free;
end;
end.
Elena
ELENA 4.1 :
import system'net;
import system'text;
import extensions'text;
import system'io;
public program()
{
var socket := new Socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
socket.connect("127.0.0.1",256);
var s := "hello socket world";
socket.write(AnsiEncoder.toByteArray(0, s.Length, s));
socket.close()
}
Elixir
defmodule Sockets do
require Logger
def send_message(port, message) do
{:ok, socket} = :gen_tcp.connect('localhost', port, [])
:gen_tcp.send(socket, message)
end
end
Sockets.send_message(256, "hello socket world")
Emacs Lisp
Emacs treats network connections as sub-processes. make-network-process
is the low-level socket creation,
(let ((proc (make-network-process :name "my sock"
:host 'local ;; or hostname string
:service 256)))
(process-send-string proc "hello socket world")
(delete-process proc))
Erlang
-module(socket).
-export([start/0]).
start() ->
{ok, Sock} = gen_tcp:connect("localhost", 256,
[binary, {packet, 0}]),
ok = gen_tcp:send(Sock, "hello socket world"),
ok = gen_tcp:close(Sock).
Factor
"localhost" 256 <inet> utf8 [ "hello socket world" print ] with-client
Fantom
using inet
class Socket
{
public static Void main ()
{
sock := TcpSocket()
sock.connect(IpAddr("localhost"), 256)
sock.out.printLine("hello socket world")
sock.out.flush
sock.close
}
}
Forth
include unix/socket.fs
s" localhost" 256 open-socket
dup s" hello socket world" rot write-socket
close-socket
Frink
s = newJava["java.net.Socket", ["localhost", 250]]
w = new Writer[s.getOutputStream[]]
w.println["hello socket world"]
w.close[]
Go
package main
import (
"fmt"
"net"
)
func main() {
conn, err := net.Dial("tcp", "localhost:256")
if err != nil {
fmt.Println(err)
return
}
defer conn.Close()
_, err = conn.Write([]byte("hello socket world"))
if err != nil {
fmt.Println(err)
}
}
- Test with nc:
$ sudo nc -l 256 & go run sock.go [2] 19754 hello socket world[2]+ Done sudo nc -l 256 $
Groovy
s = new java.net.Socket("localhost", 256)
s << "hello socket world"
s.close()
Haskell
import Network
main = withSocketsDo $ sendTo "localhost" (PortNumber $ toEnum 256) "hello socket world"
Icon and Unicon
Icon
Note: Socket support in native Icon is limited and requires the external helper function cfunc.
Unicon
Unicon integrated TCP/IP networking and messaging.
procedure main(arglist) #: usage socket port hostname or socket port
hello(arglist[2]|"",arglist[1])
end
procedure hello(host,port)
local s
/host := ""
host ||:= ":"
host ||:= 0 < 65536 > port | runerr(103,port)
if s := open(host,"n") then {
write(s, "hello socket world.")
close(s)
}
else stop("Unable to connect to ",host,":",port)
return
end
IDL
socket, unit, 'localhost',256,/get_lun
printf,unit,"hello socket world"
close, unit
"Well-known" port numbers (under 1024 -- such as 256) can also be specified by name (in this case 'RAP').
If there is no listener on this port, this will hang for a while before timing out.
J
sdcheck
raises assertions if anything goes wrong:
coinsert'jsocket' [ require 'socket' NB. Sockets library
socket =. >{.sdcheck sdsocket'' NB. Open a socket
host =. sdcheck sdgethostbyname 'localhost' NB. Resolve host
sdcheck sdconnect socket ; host ,< 256 NB. Create connection to port 256
sdcheck 'hello socket world' sdsend socket , 0 NB. Send msg
Java
import java.io.IOException;
import java.net.*;
public class SocketSend {
public static void main(String args[]) throws IOException {
sendData("localhost", "hello socket world");
}
public static void sendData(String host, String msg) throws IOException {
Socket sock = new Socket( host, 256 );
sock.getOutputStream().write(msg.getBytes());
sock.getOutputStream().flush();
sock.close();
}
}
Encapsulating the Socket
's OutputStream
in a PrintStream
(for data) or PrintWriter
(for text) may be easier in more complex programs for their auto-flush abilities, encoding management, and their overloaded print
and println
methods. The write
method from the original OutputStream
will still be available.
Jsish
#!/usr/bin/env jsish
function sockets() {
var sock = new Socket({client:true, port:256, noAsync:true, udp:true});
sock.send(-1, 'hello socket world');
sock.close();
}
;sockets();
/*
=!EXPECTSTART!=
sockets() ==> undefined
=!EXPECTEND!=
*/
- Output:
prompt$ jsish -u sockets.jsi [PASS] sockets.jsi
Julia
socket = connect("localhost",256)
write(socket, "hello socket world")
close(socket)
Kotlin
// version 1.2.21
import java.net.Socket
fun main(args: Array<String>) {
val sock = Socket("localhost", 256)
sock.use {
it.outputStream.write("hello socket world".toByteArray())
}
}
Lasso
local(net) = net_tcp
#net->connect('127.0.0.1',256)
#net->dowithclose => {
#net->writestring('Hello World')
}
Lua
socket = require "socket"
host, port = "127.0.0.1", 256
sid = socket.udp()
sid:sendto( "hello socket world", host, port )
sid:close()
MACRO-10
TITLE SOCKET
COMMENT !
Socket Example ** PDP-10 Assembly Language (KJX 2022)
Assembler: MACRO-10 Operating System: TOPS-20 V7
On TOPS-20, TCP-connections are made by opening a special
file on the "TCP:" device (in this case "TCP:256"). Apart
from the funky filename, there is virtually no difference
between opening files on disk and creating TCP-connections
or endpoints, so we go through the usual sequence of GTJFN
(= get file-handle), OPENF (open file), finally followed
by CLOSF (close file).
!
SEARCH MONSYM,MACSYM ;Load symbolic names for syscalls.
.REQUIRE SYS:MACREL
STDAC. ;Define standard register names.
JFN: BLOCK 1 ;File handle for TCP connection.
TCPFN: ASCIZ /TCP:256/ ;TCP "filename"
STR: ASCIZ /Hello World!/ ;String to send.
STRLEN= <.-STR>*5 ;Length of string.
GO:: RESET% ;Initialize process.
;; Get a file-handle (JFN) for the TCP-connection:
MOVX T1,GJ%SHT ;Do "short" GTJFN% call.
HRROI T2,TCPFN ;TCP "filename" into T2.
GTJFN% ;Get file-handle.
ERJMPS ERROR ; Handle errors.
MOVEM T1,JFN ;Store JFN we got.
;; Open the "file":
HRRZ T1,JFN ;File-handle without flags into T1.
MOVX T2,FLD(8,OF%BSZ)!OF%RD!OF%WR ;8bit bytes, read+write.
OPENF% ;Open file.
ERJMPS ERROR ; Handle errors.
;; Write the string.
MOVE T1,JFN ;File-handle into T1.
HRROI T2,STR ;String-pointer into T2.
MOVEI T3,STRLEN ;Length of string into T3.
SOUT% ;Write string.
ERJMPS ERROR ; Handle errors.
;; Close file.
HRRZ T1,JFN ;Get file-handle into T1.
CLOSF% ;Close file.
ERJMPS ERROR ; Handle errors.
;; End program.
RESET% ;Reset, to release JFN.
HALTF% ;Halt program.
JRST GO ;Allow for continue-command.
;;
;; ERROR: Print standardized error-message by means of ERSTR.
;; This is similar to perror() in C.
;;
ERROR: MOVEI T1,.PRIOU ;Print on standard output.
MOVE T2,[.FHSLF,,-1] ;Own process, last error.
SETZ T3 ;No length-limit on error msg.
ERSTR% ;Print error-message.
JFCL ; Ignore errors from ERSTR%.
JFCL ; Dito.
RESET% ;Reset, to release JFN.
HALTF% ;Halt program.
JRST GO ;Allow for continue-command.
END GO
Mathematica /Wolfram Language
socket = SocketConnect["localhost:256", "TCP"];
WriteString[socket, "hello socket world"];
Close[socket];
Myrddin
use std
const main = {
match std.dial("tcp!localhost!256")
| `std.Ok fd:
std.write(fd, "hello socket world")
std.close(fd)
| `std.Err err:
std.fatal("could not open fd: {}\n", err)
;;
}
Nanoquery
import Nanoquery.Net
p = new(Port)
p.connect("localhost", 256)
p.write("hello socket world")
p.close()
Neko
/**
Sockets in Neko
Tectonics:
nekoc sockets.neko
sudo nc -vulp 256 & sudo neko sockets
*/
var socket_init = $loader.loadprim("std@socket_init", 0);
var socket_new = $loader.loadprim("std@socket_new", 1);
var host_resolve = $loader.loadprim("std@host_resolve", 1);
var socket_connect = $loader.loadprim("std@socket_connect", 3);
var socket_write = $loader.loadprim("std@socket_write", 2);
var socket_close = $loader.loadprim("std@socket_close", 1);
/* Initialize Neko socket API */
socket_init();
/* true; UDP, false; TCP */
var socket = socket_new(true);
var c = socket_connect(socket, host_resolve("localhost"), 256);
socket_write(socket, "hello socket world");
socket_close(socket);
For testing on port 256, root powers required
- Output:
prompt$ nekoc sockets.neko prompt$ sudo nc -vulp 256 & sudo neko sockets [1] 4475 Ncat: Version 7.60 ( https://nmap.org/ncat ) Ncat: Listening on :::256 Ncat: Listening on 0.0.0.0:256 hello socket world prompt$ [1]+ Stopped sudo nc -vulp 256
Nemerle
using System.Text;
using System.Net.Sockets;
module Program
{
Main() : void
{
def sock = Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect("127.0.0.1", 1000);
_ = sock.Send(Encoding.ASCII.GetBytes("Hell, world!"));
sock.Close();
}
}
NetRexx
<
/* NetRexx */
options replace format comments java crossref symbols nobinary
import java.net.
runSample(arg)
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
parse arg host':'port':'message
if host = '' then host = 'localhost'
if port = '' then port = 256
if message = '' then message = 'hello socket world'
sendToSocket(host, port, message)
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method sendToSocket(host, port, message) public static
do
sokt = Socket(host, port)
soks = sokt.getOutputStream()
soks.write((String message).getBytes())
soks.flush()
sokt.close()
catch ix = IOException
ix.printStackTrace()
end
return
NewLISP
(set 'socket (net-connect "localhost" 256))
(net-send socket "hello socket world")
(net-close socket)
(exit)
Nim
import net
var s = newSocket()
s.connect("localhost", Port(256))
s.send("Hello Socket World")
s.close()
Objeck
use Net;
bundle Default {
class Socket {
function : Main(args : String[]) ~ Nil {
socket := TCPSocket->New("localhost", 256);
if(socket->IsOpen()) {
socket->WriteString("hello socket world");
socket->Close();
}
}
}
}
Objective-C
(untested)
// declare the class to conform to NSStreamDelegate protocol
// in some method
NSOutputStream *oStream;
[NSStream getStreamsToHost:[NSHost hostWithName:@"localhost"] port:256 inputStream:NULL outputStream:&oStream];
[oStream setDelegate:self];
[oStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[oStream open];
// later, in the same class:
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent {
NSOutputStream *oStream = (NSOutputStream *)aStream;
if (streamEvent == NSStreamEventHasBytesAvailable) {
NSString *str = @"hello socket world";
const char *rawstring = [str UTF8String];
[oStream write:rawstring maxLength:strlen(rawstring)];
[oStream close];
}
}
OCaml
open Unix
let init_socket addr port =
let inet_addr = (gethostbyname addr).h_addr_list.(0) in
let sockaddr = ADDR_INET (inet_addr, port) in
let sock = socket PF_INET SOCK_STREAM 0 in
connect sock sockaddr;
(* convert the file descriptor into high-level channels: *)
let outchan = out_channel_of_descr sock in
let inchan = in_channel_of_descr sock in
(inchan, outchan)
let () =
let ic, oc = init_socket "localhost" 256 in
output_string oc "hello socket world";
;;
Oz
declare
Socket = {New Open.socket init}
in
{Socket connect(port:256)}
{Socket write(vs:"hello socket world")}
{Socket close}
Pascal
Tested using nc -l 256
, on both macOS Sierra and Windows 7, compiled using Free Pascal in the default FPC mode.
Very similar to the example in C.
See also Delphi.
Program Sockets_ExampleA;
Uses
{ Free Pascal RTL sockets unit }
sockets;
Var
TCP_Sock: integer;
Remote_Addr: TSockAddr;
Message: string;
PMessage: Pchar;
Message_Len: integer;
Begin
{ Fill the record (struct) with the server's address information }
With Remote_Addr do
begin
Sin_family := AF_INET;
Sin_addr := StrToNetAddr('127.0.0.1');
Sin_port := HtoNs(256);
end;
{ Returns an IPv4 TCP socket descriptor }
TCP_Sock := fpSocket(AF_INET, SOCK_STREAM, IPPROTO_IP);
{ Most routines in this unit return -1 on failure }
If TCP_Sock = -1 then
begin
WriteLn('Failed to create new socket descriptor');
Halt(1);
end;
{ Attempt to connect to the address supplied above }
If fpConnect(TCP_Sock, @Remote_Addr, SizeOf(Remote_Addr)) = -1 then
begin
{ Specifc error codes can be retrieved by calling the SocketError function }
WriteLn('Failed to contact server');
Halt(1);
end;
{ Finally, send the message to the server and disconnect }
Message := 'Hello socket world';
PMessage := @Message;
Message_Len := StrLen(PMessage);
If fpSend(TCP_Sock, PMessage, Message_Len, 0) <> Message_Len then
begin
WriteLn('An error occurred while sending data to the server');
Halt(1);
end;
CloseSocket(TCP_Sock);
End.
Variant without superfluous additions:
Program Sockets_ExampleB;
Uses
sockets;
Var
TCP_Sock: integer;
Remote_Addr: TSockAddr;
Message: string;
PMessage: Pchar;
Message_Len: integer;
Begin
Remote_Addr.Sin_family := AF_INET;
Remote_Addr.Sin_addr := StrToNetAddr('127.0.0.1');
Remote_Addr.Sin_port := HtoNs(256);
TCP_Sock := fpSocket(AF_INET, SOCK_STREAM, IPPROTO_IP);
fpConnect(TCP_Sock, @Remote_Addr, SizeOf(Remote_Addr));
Message := 'Hello socket world';
PMessage := @Message;
Message_Len := StrLen(PMessage);
fpSend(TCP_Sock, PMessage, Message_Len, 0);
End.
Perl
use Socket;
$host = gethostbyname('localhost');
$in = sockaddr_in(256, $host);
$proto = getprotobyname('tcp');
socket(Socket_Handle, AF_INET, SOCK_STREAM, $proto);
connect(Socket_Handle, $in);
send(Socket_Handle, 'hello socket world', 0, $in);
close(Socket_Handle);
Object oriented version.
use Socket::Class;
$sock = Socket::Class->new(
'remote_port' => 256,
) || die Socket::Class->error;
$sock->send('hello socket world');
$sock->free;
Phix
Note this fails for me with "connection refused", just like the Go/Python/Ruby entries.
without js -- (sockets) include builtins\sockets.e constant msg = "hello socket world" atom sock = socket(AF_INET, SOCK_STREAM) if sock>=0 then atom pSockAddr = sockaddr_in(AF_INET, "localhost", 256) integer res = connect(sock, pSockAddr) if res=SOCKET_ERROR then crash("connect (%v)",{get_socket_error()}) end if string pm = msg while true do integer len = length(pm), slen = send(sock, pm) if slen<0 or slen=len then exit end if pm = pm[slen+1..$] end while closesocket(sock) end if WSACleanup()
PHP
$socket = fsockopen('localhost', 256);
fputs($socket, 'hello socket world');
fclose($socket);
PicoLisp
(when (connect "localhost" 256)
(out @ (prinl "hello socket world"))
(close @) )
Pike
import Stdio;
int main(){
object con = File();
con->connect("127.0.0.1",256);
con->write("hello socket world");
con->close();
}
Prolog
This works with Gnu Prolog. Other implementations will have different predicates.
start(Port) :- socket('AF_INET',Socket),
socket_connect(Socket, 'AF_INET'(localhost,Port), Input, Output),
write(Output, 'hello socket world'),
flush_output(Output),
close(Output),
close(Input).
PureBasic
InitNetwork()
ConnectionID = OpenNetworkConnection("localhost", 256)
SendNetworkString(ConnectionID, "hello socket world")
CloseNetworkConnection(ConnectionID)
Python
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 256))
sock.sendall("hello socket world")
sock.close()
R
s <- make.socket(port = 256)
write.socket(s, "hello socket world")
close.socket(s)
Racket
#lang racket
(let-values ([(in out) (tcp-connect "localhost" 256)])
(display "hello socket world\n" out)
(close-output-port out))
Raku
(formerly Perl 6)
Will fail with a connect error if there is not a socket server of some kind available on the specified host and port.
my $host = '127.0.0.1';
my $port = 256;
my $client = IO::Socket::INET.new(:$host, :$port);
$client.print( 'hello socket world' );
$client.close;
Rhope
Socket Send(0,0)
|:
[New@Net Client["localhost",256]]Put String["hello socket world"]
:|
The connection is automatically closed when the object is freed.
Ring
Load "guilib.ring"
new qApp {
oClient = new Client { client() }
exec()
}
Class Client
win1 oTcpSocket
func client
win1 = new qwidget()
new qpushbutton(win1) {
setgeometry(50,50,100,30)
settext("connect")
setclickevent("oClient.Connect()")
}
win1 {
setwindowtitle("client")
setgeometry(10,100,400,400)
show()
}
func connect
oTcpSocket = new qTcpSocket(win1) {
setconnectedevent("oClient.pConnected()")
connecttohost("127.0.0.1",256,3,0)
waitforconnected(5000)
}
func pConnected
cStr = "hello socket world"
write(cStr,len(cStr))
flush()
waitforbyteswritten(300000)
close()
Ruby
require 'socket'
sock = TCPSocket.open("localhost", 256)
sock.write("hello socket world")
sock.close
Rust
use std::io::prelude::*;
use std::net::TcpStream;
fn main() {
// Open a tcp socket connecting to 127.0.0.1:256, no error handling (unwrap)
let mut my_stream = TcpStream::connect("127.0.0.1:256").unwrap();
// Write 'hello socket world' to the stream, ignoring the result of write
let _ = my_stream.write(b"hello socket world");
} // <- my_stream's drop function gets called, which closes the socket
Scala
import java.net.Socket
object sendSocketData {
def sendData(host: String, msg: String) {
val sock = new Socket(host, 256)
sock.getOutputStream().write(msg.getBytes())
sock.getOutputStream().flush()
sock.close()
}
sendData("localhost", "hello socket world")
}
Scheme
(let ((s (socket PF_INET SOCK_STREAM 0)))
(connect s AF_INET (inet-pton AF_INET "127.0.0.1") 256)
(display "hello socket world" s))
Seed7
The library socket.s7i defines the function openInetSocket, which returns a connected internet socket file at a port at localhost.
$ include "seed7_05.s7i";
include "socket.s7i";
const proc: main is func
local
var file: sock is STD_NULL;
begin
sock := openInetSocket(256);
writeln(sock, "hello socket world");
close(sock);
end func;
SenseTalk
set SocketID to "localhost:256"
open socket SocketID
write "Hello socket world!" to socket SocketID
close socket SocketID
Sidef
var host = Socket.gethostbyname('localhost');
var in = Socket.sockaddr_in(256, host);
var proto = Socket.getprotobyname('tcp');
var sock = Socket.open(Socket.AF_INET, Socket.SOCK_STREAM, proto);
sock.connect(in);
sock.send('hello socket world', 0, in);
sock.close;
Slate
This uses fairly verbose and low level messages. This will probably be simplified in the future.
[ | socket |
[ | addr stream |
addr: (Net SocketAddress newOn: '127.0.0.1:256').
socket: (Net Socket newFor: addr domain type: Net Socket Types Stream protocol: Net Socket Protocols Default).
socket connectTo: addr.
stream: (Net SocketStream newOn: socket).
stream nextPutAll: ('hello socket world' as: ByteArray).
stream flush
] ensure: [socket close]
] do.
Smalltalk
This is taken from here with few modification to fit the task better.
PackageLoader fileInPackage: 'TCP'!
Object subclass: #HelloSocket
instanceVariableNames: 'ss'
classVariableNames: ''
poolDictionaries: ''
category: 'SimpleEcho'!
!HelloSocket class methodsFor: 'instance creation'!
port: anInteger
| ses |
ses := super new.
ses init: anInteger.
^ses
!!
!HelloSocket methodsFor: 'instance initialization'!
init: anInteger
ss := (TCP.ServerSocket port: anInteger).
^self
!!
!HelloSocket methodsFor: 'running'!
run
| s |
[
ss waitForConnection.
s := (ss accept).
[self handleSocket: s] fork
] repeat
!!
!HelloSocket methodsFor: 'handling'!
handleSocket: s
| msg |
msg := 'hello socket world'.
msg displayOn: s.
(String with: (Character value: 10)) displayOn: s.
s flush
!!
Smalltalk at: #helloServer put: (HelloSocket port: 2560).
helloServer run.
Symsyn
'127.0.0.1' $addr
connect $addr 256 sok
'hello socket world' [sok]
close sok
Standard ML
val txt = Word8VectorSlice.full (Byte.stringToBytes "hello world" ) ;
val set = fn socket => fn ipnr => fn portnr => fn text =>
(
Socket.connect (socket, INetSock.toAddr ( Option.valOf (NetHostDB.fromString(ipnr) ) , portnr )) ;
Socket.sendVec(socket, text) before Socket.close socket
)
;
call
set ( INetSock.TCP.socket () ) "127.0.0.1" 256 txt ;
Tcl
set io [socket localhost 256]
puts -nonewline $io "hello socket world"
close $io
Toka
needs sockets
#! A simple abstraction layer that makes writing trivial servers easy
value| server.socket server.connection server.action |
[ ( n- ) pBind to server.socket ] is server.setSocket
[ ( - ) server.socket pAccept to server.connection ] is server.acceptConnection
[ ( - ) server.connection pClose drop ] is server.closeConnection
[ ( $- ) >r server.connection r> string.getLength pWrite drop ] is server.send
[ ( an- ) server.connection -rot pRead drop ] is server.recieve
[ ( qn- ) swap to server.action server.setSocket
[ server.acceptConnection server.action invoke server.closeConnection TRUE ] whileTrue ] is server.start
#! The actual server
[ " hello socket world" server.send ] 256 server.start
TXR
(let* ((server (first (getaddrinfo "localhost" 256)))
(sock (open-socket server.family sock-stream)))
(sock-connect sock server)
(put-string "hello socket world"))
UNIX Shell
Using netcat:
echo "hello socket world" | nc localhost 256
When the connection fails, nc
exits 1. To see an error message, use nc -v localhost 256
.
Ursa
decl port p
p.connect "localhost" 256
out "hello socket world" endl p
p.close
Visual Basic .NET
Imports System
Imports System.IO
Imports System.Net.Sockets
Public Class Program
Public Shared Sub Main(ByVal args As String[])
Dim tcp As New TcpClient("localhost", 256)
Dim writer As New StreamWriter(tcp.GetStream())
writer.Write("hello socket world")
writer.Flush()
tcp.Close()
End Sub
End Class
Wren
An embedded program so we can ask the C host to call the relevant library functions for us.
/* sockets.wren */
var AF_UNSPEC = 0
var SOCK_STREAM = 1
foreign class AddrInfo {
foreign static getAddrInfo(name, service, req, pai)
construct new() {}
foreign family
foreign family=(f)
foreign sockType
foreign sockType=(st)
foreign protocol
foreign addr
foreign addrLen
}
foreign class AddrInfoPtr {
construct new() {}
foreign deref
foreign free()
}
foreign class SockAddrPtr {
construct new() {}
}
class Socket {
foreign static create(domain, type, protocol)
foreign static connect(fd, addr, len)
foreign static send(fd, buf, n, flags)
foreign static close(fd)
}
var msg = "hello socket world\n"
var hints = AddrInfo.new()
hints.family = AF_UNSPEC
hints.sockType = SOCK_STREAM
var addrInfoPtr = AddrInfoPtr.new()
if (AddrInfo.getAddrInfo("localhost", "256", hints, addrInfoPtr) == 0){
var addrs = addrInfoPtr.deref
var sock = Socket.create(addrs.family, addrs.sockType, addrs.protocol)
if (sock >= 0) {
var stat = Socket.connect(sock, addrs.addr, addrs.addrLen)
if (stat >= 0) {
var pm = msg
while (true) {
var len = pm.count
var slen = Socket.send(sock, pm, len, 0)
if (slen < 0 || slen >= len) break
pm = pm[slen..-1]
}
}
var status = Socket.close(sock)
if (status != 0) System.print("Failed to close socket.")
}
addrInfoPtr.free()
}
Now embed this script in the following C program, compile and run it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include "wren.h"
/* C <=> Wren interface functions */
void C_addrInfoAllocate(WrenVM* vm) {
wrenSetSlotNewForeign(vm, 0, 0, sizeof(struct addrinfo));
}
void C_addrInfoPtrAllocate(WrenVM* vm) {
wrenSetSlotNewForeign(vm, 0, 0, sizeof(struct addrinfo*));
}
void C_sockAddrPtrAllocate(WrenVM* vm) {
wrenSetSlotNewForeign(vm, 0, 0, sizeof(struct sockaddr*));
}
void C_getAddrInfo(WrenVM* vm) {
const char *name = wrenGetSlotString(vm, 1);
const char *service = wrenGetSlotString(vm, 2);
const struct addrinfo *req = (const struct addrinfo *)wrenGetSlotForeign(vm, 3);
struct addrinfo** ppai = (struct addrinfo**)wrenGetSlotForeign(vm, 4);
int status = getaddrinfo(name, service, req, ppai);
wrenSetSlotDouble(vm, 0, (double)status);
}
void C_family(WrenVM* vm) {
struct addrinfo* pai = (struct addrinfo*)wrenGetSlotForeign(vm, 0);
wrenSetSlotDouble(vm, 0, (double)(pai->ai_family));
}
void C_setFamily(WrenVM* vm) {
struct addrinfo* pai = (struct addrinfo*)wrenGetSlotForeign(vm, 0);
int f = (int)wrenGetSlotDouble(vm, 1);
pai->ai_family = f;
}
void C_sockType(WrenVM* vm) {
struct addrinfo* pai = (struct addrinfo*)wrenGetSlotForeign(vm, 0);
wrenSetSlotDouble(vm, 0, (double)(pai->ai_socktype));
}
void C_setSockType(WrenVM* vm) {
struct addrinfo* pai = (struct addrinfo*)wrenGetSlotForeign(vm, 0);
int type = (int)wrenGetSlotDouble(vm, 1);
pai->ai_socktype = type;
}
void C_protocol(WrenVM* vm) {
struct addrinfo* pai = (struct addrinfo*)wrenGetSlotForeign(vm, 0);
wrenSetSlotDouble(vm, 0, (double)(pai->ai_protocol));
}
void C_addr(WrenVM* vm) {
wrenEnsureSlots(vm, 2);
struct addrinfo* pai = (struct addrinfo*)wrenGetSlotForeign(vm, 0);
wrenGetVariable(vm, "main", "SockAddrPtr", 1);
struct sockaddr **ppsa = (struct sockaddr**)wrenSetSlotNewForeign(vm, 0, 1, sizeof(struct sockaddr*));
*ppsa = pai->ai_addr;
}
void C_addrLen(WrenVM* vm) {
struct addrinfo* pai = (struct addrinfo*)wrenGetSlotForeign(vm, 0);
wrenSetSlotDouble(vm, 0, (double)(pai->ai_addrlen));
}
void C_deref(WrenVM* vm) {
wrenEnsureSlots(vm, 2);
struct addrinfo** ppai = (struct addrinfo**)wrenGetSlotForeign(vm, 0);
wrenGetVariable(vm, "main", "AddrInfo", 1);
struct addrinfo *pai = (struct addrinfo*)wrenSetSlotNewForeign(vm, 0, 1, sizeof(struct addrinfo));
*pai = **ppai;
}
void C_free(WrenVM* vm) {
struct addrinfo* pai = *(struct addrinfo**)wrenGetSlotForeign(vm, 0);
freeaddrinfo(pai);
}
void C_create(WrenVM* vm) {
int domain = (int)wrenGetSlotDouble(vm, 1);
int type = (int)wrenGetSlotDouble(vm, 2);
int protocol = (int)wrenGetSlotDouble(vm, 3);
int fd = socket(domain, type, protocol);
wrenSetSlotDouble(vm, 0, (double)fd);
}
void C_connect(WrenVM* vm) {
int fd = (int)wrenGetSlotDouble(vm, 1);
__CONST_SOCKADDR_ARG *psa = (__CONST_SOCKADDR_ARG *)wrenGetSlotForeign(vm, 2);
socklen_t len = (socklen_t)wrenGetSlotDouble(vm, 3);
int status = connect(fd, *psa, len);
wrenSetSlotDouble(vm, 0, (double)status);
}
void C_send(WrenVM* vm) {
int fd = (int)wrenGetSlotDouble(vm, 1);
const char *buf = (const char *)wrenGetSlotString(vm, 2);
size_t n = (size_t)wrenGetSlotDouble(vm, 3);
int flags = (int)wrenGetSlotDouble(vm, 4);
ssize_t size = send(fd, (const void*)buf, n, flags);
wrenSetSlotDouble(vm, 0, (double)size);
}
void C_close(WrenVM* vm) {
int fd = (int)wrenGetSlotDouble(vm, 1);
int status = close(fd);
wrenSetSlotDouble(vm, 0, (double)status);
}
WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
WrenForeignClassMethods methods;
methods.allocate = NULL;
methods.finalize = NULL;
if (strcmp(module, "main") == 0) {
if (strcmp(className, "AddrInfo") == 0) {
methods.allocate = C_addrInfoAllocate;
} else if (strcmp(className, "AddrInfoPtr") == 0) {
methods.allocate = C_addrInfoPtrAllocate;
} else if (strcmp(className, "SockAddPtr") == 0) {
methods.allocate = C_sockAddrPtrAllocate;
}
}
return methods;
}
WrenForeignMethodFn bindForeignMethod(
WrenVM* vm,
const char* module,
const char* className,
bool isStatic,
const char* signature) {
if (strcmp(module, "main") == 0) {
if (strcmp(className, "AddrInfo") == 0) {
if ( isStatic && strcmp(signature, "getAddrInfo(_,_,_,_)") == 0) return C_getAddrInfo;
if (!isStatic && strcmp(signature, "family") == 0) return C_family;
if (!isStatic && strcmp(signature, "family=(_)") == 0) return C_setFamily;
if (!isStatic && strcmp(signature, "sockType") == 0) return C_sockType;
if (!isStatic && strcmp(signature, "sockType=(_)") == 0) return C_setSockType;
if (!isStatic && strcmp(signature, "protocol") == 0) return C_protocol;
if (!isStatic && strcmp(signature, "addr") == 0) return C_addr;
if (!isStatic && strcmp(signature, "addrLen") == 0) return C_addrLen;
} else if (strcmp(className, "AddrInfoPtr") == 0) {
if (!isStatic && strcmp(signature, "deref") == 0) return C_deref;
if (!isStatic && strcmp(signature, "free()") == 0) return C_free;
} else if (strcmp(className, "Socket") == 0) {
if ( isStatic && strcmp(signature, "create(_,_,_)") == 0) return C_create;
if ( isStatic && strcmp(signature, "connect(_,_,_)") == 0) return C_connect;
if ( isStatic && strcmp(signature, "send(_,_,_,_)") == 0) return C_send;
if ( isStatic && strcmp(signature, "close(_)") == 0) return C_close;
}
}
return NULL;
}
static void writeFn(WrenVM* vm, const char* text) {
printf("%s", text);
}
void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
switch (errorType) {
case WREN_ERROR_COMPILE:
printf("[%s line %d] [Error] %s\n", module, line, msg);
break;
case WREN_ERROR_STACK_TRACE:
printf("[%s line %d] in %s\n", module, line, msg);
break;
case WREN_ERROR_RUNTIME:
printf("[Runtime Error] %s\n", msg);
break;
}
}
char *readFile(const char *fileName) {
FILE *f = fopen(fileName, "r");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *script = malloc(fsize + 1);
fread(script, 1, fsize, f);
fclose(f);
script[fsize] = 0;
return script;
}
int main(int argc, char **argv) {
WrenConfiguration config;
wrenInitConfiguration(&config);
config.writeFn = &writeFn;
config.errorFn = &errorFn;
config.bindForeignClassFn = &bindForeignClass;
config.bindForeignMethodFn = &bindForeignMethod;
WrenVM* vm = wrenNewVM(&config);
const char* module = "main";
const char* fileName = "sockets2.wren";
char *script = readFile(fileName);
WrenInterpretResult result = wrenInterpret(vm, module, script);
switch (result) {
case WREN_RESULT_COMPILE_ERROR:
printf("Compile Error!\n");
break;
case WREN_RESULT_RUNTIME_ERROR:
printf("Runtime Error!\n");
break;
case WREN_RESULT_SUCCESS:
break;
}
wrenFreeVM(vm);
free(script);
return 0;
}
- Output:
$ gcc sockets.c -o sockets -lwren -lm $ sudo nc -l 256 & ./sockets [199] 10818 hello socket world
X86 Assembly
;using sockets on linux with the 0x80 inturrprets.
;
;assemble
; nasm -o socket.o -f elf32 -g socket.asm
;link
; ld -o socket socket.o
;
;
;Just some assigns for better readability
%assign SOCK_STREAM 1
%assign AF_INET 2
%assign SYS_socketcall 102
%assign SYS_SOCKET 1
%assign SYS_CONNECT 3
%assign SYS_SEND 9
%assign SYS_RECV 10
section .text
global _start
;--------------------------------------------------
;Functions to make things easier. :]
;--------------------------------------------------
_socket:
mov [cArray+0], dword AF_INET
mov [cArray+4], dword SOCK_STREAM
mov [cArray+8], dword 0
mov eax, SYS_socketcall
mov ebx, SYS_SOCKET
mov ecx, cArray
int 0x80
ret
_connect:
call _socket
mov dword [sock], eax
mov dx, si
mov byte [edi+3], dl
mov byte [edi+2], dh
mov [cArray+0], eax ;sock;
mov [cArray+4], edi ;&sockaddr_in;
mov edx, 16
mov [cArray+8], edx ;sizeof(sockaddr_in);
mov eax, SYS_socketcall
mov ebx, SYS_CONNECT
mov ecx, cArray
int 0x80
ret
_send:
mov edx, [sock]
mov [sArray+0],edx
mov [sArray+4],eax
mov [sArray+8],ecx
mov [sArray+12], dword 0
mov eax, SYS_socketcall
mov ebx, SYS_SEND
mov ecx, sArray
int 0x80
ret
_exit:
push 0x1
mov eax, 1
push eax
int 0x80
_print:
mov ebx, 1
mov eax, 4
int 0x80
ret
;--------------------------------------------------
;Main code body
;--------------------------------------------------
_start:
mov esi, szIp
mov edi, sockaddr_in
xor eax,eax
xor ecx,ecx
xor edx,edx
.cc:
xor ebx,ebx
.c:
lodsb
inc edx
sub al,'0'
jb .next
imul ebx,byte 10
add ebx,eax
jmp short .c
.next:
mov [edi+ecx+4],bl
inc ecx
cmp ecx,byte 4
jne .cc
mov word [edi], AF_INET
mov esi, szPort
xor eax,eax
xor ebx,ebx
.nextstr1:
lodsb
test al,al
jz .ret1
sub al,'0'
imul ebx,10
add ebx,eax
jmp .nextstr1
.ret1:
xchg ebx,eax
mov [sport], eax
mov si, [sport]
call _connect
cmp eax, 0
jnz short _fail
mov eax, msg
mov ecx, msglen
call _send
call _exit
_fail:
mov edx, cerrlen
mov ecx, cerrmsg
call _print
call _exit
_recverr:
call _exit
_dced:
call _exit
section .data
cerrmsg db 'failed to connect :(',0xa
cerrlen equ $-cerrmsg
msg db 'Hello socket world!',0xa
msglen equ $-msg
szIp db '127.0.0.1',0
szPort db '256',0
section .bss
sock resd 1
;general 'array' for syscall_socketcall argument arg.
cArray resd 1
resd 1
resd 1
resd 1
;send 'array'.
sArray resd 1
resd 1
resd 1
resd 1
;duh?
sockaddr_in resb 16
;..
sport resb 2
buff resb 1024
Operates in non-blocking mode.
.586
.model flat,stdcall
option casemap:none
include /masm32/include/windows.inc
include /masm32/include/user32.inc
include /masm32/include/kernel32.inc
include /masm32/include/ws2_32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/ws2_32.lib
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
.data
ClassName db "MainWinClass",0
AppName db "Async Sockets",0
szSockStr db "Hello socket world!",13,10,0
szIp db "127.0.0.1",0
port dd 256
wsa WSADATA <>
sa sockaddr_in <>
.data?
hInstance dd ?
CommandLine dd ?
sock dd ?
.const
WM_SOCK equ WM_USER+100
.code
start:
invoke WSAStartup, 200h, addr wsa
.if eax!=NULL
invoke ExitProcess, eax
.else
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
.endif
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke socket, AF_INET,SOCK_STREAM, 0
.if eax==INVALID_SOCKET
;error
.endif
mov sock, eax
invoke WSAAsyncSelect, sock, hWnd, WM_SOCK, FD_CONNECT or FD_CLOSE
.if eax==INVALID_SOCKET
;error!
.endif
mov sa.sin_family, AF_INET
invoke inet_addr, addr szIp
mov sa.sin_addr, eax
invoke htons, port
mov sa.sin_port, ax
invoke connect, sock, addr sa, sizeof sa
.if eax==SOCKET_ERROR
invoke WSAGetLastError
.if eax!=WSAEWOULDBLOCK
;real error.
.endif
.endif
.elseif uMsg==WM_SOCK
mov edx, lParam
.if dx==FD_CONNECT
shr edx, 16
.if dx==NULL
invoke lstrlen, addr szSockStr
invoke send, sock, addr szSockStr, eax, 0
.else
;error
.endif
.elseif dx==FD_CLOSE
shr edx, 16
.if dx==NULL
invoke SendMessage, hWnd, WM_DESTROY, 0, 0
.endif
.endif
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
This example works in blocking mode.
.586
.model flat,stdcall
option casemap:none
include /masm32/include/windows.inc
include /masm32/include/user32.inc
include /masm32/include/kernel32.inc
include /masm32/include/ws2_32.inc
includelib /masm32/lib/user32.lib
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/ws2_32.lib
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
.data
ClassName db "MainWinClass",0
AppName db "Blocking Sockets",0
szSockStr db "Hello socket world!",13,10,0
szIp db "127.0.0.1",0
port dd 256
wsa WSADATA <>
sa sockaddr_in <>
.data?
hInstance dd ?
CommandLine dd ?
sock dd ?
.code
start:
invoke WSAStartup, 200h, addr wsa
.if eax!=NULL
invoke ExitProcess, eax
.else
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
.endif
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_BTNFACE+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_CREATE
invoke socket, AF_INET,SOCK_STREAM, 0
.if eax==INVALID_SOCKET
;error
.endif
mov sock, eax
mov sa.sin_family, AF_INET
invoke inet_addr, addr szIp
mov sa.sin_addr, eax
invoke htons, port
mov sa.sin_port, ax
invoke connect, sock, addr sa, sizeof sa
invoke lstrlen, addr szSockStr
invoke send, sock, addr szSockStr, eax, 0
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
X86-64 Assembly
UASM 2.52
option casemap:none
option literals:on
ifndef __SOCKET_CLASS__
__SOCKET_CLASS__ equ 1
if @Platform eq windows64
WSADATA struct
wVersion dw ?
wHighVersion dw ?
iMaxSockets dw ?
iMaxUdpDg dw ?
szDescription db 256 dup (?)
szSystemStatus db 128 dup (?)
lpVendorInfo dq ?
WSADATA ends
option dllimport:<kernel32>
ExitProcess proto :word
HeapAlloc proto :qword, :dword, :qword
HeapFree proto :qword, :dword, :qword
GetProcessHeap proto
option dllimport:<ws2_32>
WSAStartup proto :word, :qword
WSACleanup proto :qword
closesocket proto :dword
option dllimport:none
exit equ ExitProcess
close equ closesocket
elseif @Platform eq linux64
malloc proto SYSTEMV :qword
free proto SYSTEMV :qword
close proto SYSTEMV :dword
exit proto SYSTEMV :dword
endif
memset proto :qword, :dword, :dword
printf proto :qword, :vararg
strlen proto :qword
getaddrinfo proto :qword, :qword, :qword, :qword
gai_strerror proto :dword
send proto :dword, :qword, :qword, :dword
socket proto :dword, :dword, :dword
connect proto :dword, :qword, :dword
freeaddrinfo proto :qword
CLASS socket_class
CMETHOD conn
CMETHOD write
ENDMETHODS
if @Platform eq windows64
wsa WSADATA <?>
endif
sock dd 0
pai dq 0
hostname dq ?
port dq ?
ENDCLASS
METHOD socket_class, Init, <VOIDARG>, <>, h:qword, p:qword
mov rbx, thisPtr
assume rbx:ptr socket_class
mov rax, h
mov [rbx].hostname, rax
mov rax, p
mov [rbx].port, rax
mov rax, rbx
assume rbx:nothing
ret
ENDMETHOD
METHOD socket_class, conn, <dword>, <>
local ht:qword
mov rbx, thisPtr
assume rbx:ptr socket_class
invoke printf, CSTR("--> Attempting connection to %s on %s",10), [rbx].hostname ,[rbx].port
if @Platform eq windows64
invoke WSAStartup, 202h, addr [rbx].wsa
endif
invoke memset, ht, 0, 0x30 ;; sizeof(struct addrinfo)
mov rax, ht
mov dword ptr [rax], 0 ;; ai_flags
mov dword ptr [rax+4], AF_INET
mov dword ptr [rax+8], SOCK_STREAM
invoke getaddrinfo, [rbx].hostname, [rbx].port, ht, addr [rbx].pai
.if rax != 0
invoke gai_strerror, eax
invoke printf, CSTR("--> Gai_strerror returned: %s",10), rax
mov rax, -1
jmp _exit
.endif
mov rax, [rbx].pai
mov edx, dword ptr [rax + 0XC] ;; pai.ai_protocol
mov ecx, dword ptr [rax + 8] ;; pai.ai_socktype
mov eax, dword ptr [rax + 4] ;; pai.ai_family
invoke socket, eax, ecx, edx
.if rax == -1
mov rax, -1
jmp _exit
.endif
mov [rbx].sock, eax
invoke printf, CSTR("--> Socket created as: %d",10), [rbx].sock
mov rax, [rbx].pai
mov edx, dword ptr [rax + 0x10] ;; pai.ai_addrlen
mov rcx, qword ptr [rax + 0x18] ;; pai.ai_addr
invoke connect, [rbx].sock, rcx, edx
.if rax == -1
invoke printf, CSTR("--> connect failed.. %i",10), rax
mov rax, -1
jmp _exit
.endif
mov rax, 0
_exit:
assume rbx:nothing
ret
ENDMETHOD
METHOD socket_class, write, <dword>, <>, b:qword
local tmp:qword
mov rbx, thisPtr
assume rbx:ptr socket_class
mov rax, b
mov tmp, rax
invoke strlen, tmp
invoke send, [rbx].sock, tmp, rax, 0
.if eax == -1
invoke printf, CSTR("--> Error in send..%d",10), rax
ret
.endif
assume rbx:nothing
ret
ENDMETHOD
METHOD socket_class, Destroy, <VOIDARG>, <>
mov rbx, thisPtr
assume rbx:ptr socket_class
invoke close, [rbx].sock
if @Platform eq windows64
invoke WSACleanup, addr [rbx].wsa
endif
.if [rbx].pai != 0
invoke freeaddrinfo, [rbx].pai
.endif
assume rbx:nothing
ret
ENDMETHOD
endif ;; __SOCKET_CLASS__
.code
main proc
local lpSocket:ptr socket_class
mov lpSocket, _NEW(socket_class, CSTR("localhost"), CSTR("256"))
lpSocket->conn()
.if rax == -1
invoke exit, 0
ret
.endif
invoke printf, CSTR("-> Connected, sending data.",10)
lpSocket->write(CSTR("Goodbye, socket world!",10))
_DELETE(lpSocket)
invoke exit, 0
ret
main endp
end
zkl
var s=Network.TCPClientSocket.connectTo("localhost",256);
s.write("hello socket world"); //-->18
s.close();
Zsh
zmodload zsh/net/tcp
ztcp localhost 256
print hello socket world >&$REPLY
- Programming Tasks
- Networking and Web Interaction
- Ada
- GNAT RTL
- Aime
- AutoHotkey
- AutoIt
- AWK
- BBC BASIC
- C
- C sharp
- C++
- Cind
- Clojure
- Common Lisp
- Usocket
- D
- Delphi
- Elena
- Elixir
- Emacs Lisp
- Erlang
- Factor
- Fantom
- Forth
- Frink
- Go
- Groovy
- Haskell
- Icon
- Unicon
- IDL
- J
- Java
- Jsish
- Julia
- Kotlin
- Lasso
- Lua
- LuaSocket
- MACRO-10
- Mathematica
- Wolfram Language
- Myrddin
- Nanoquery
- Neko
- Nemerle
- NetRexx
- NewLISP
- Nim
- Objeck
- Objective-C
- OCaml
- Oz
- Pascal
- Perl
- Phix
- PHP
- PicoLisp
- Pike
- Prolog
- PureBasic
- Python
- R
- Racket
- Raku
- Rhope
- Ring
- Ruby
- Rust
- Scala
- Scheme
- Seed7
- SenseTalk
- Sidef
- Slate
- Smalltalk
- Symsyn
- Standard ML
- Tcl
- Toka
- TXR
- UNIX Shell
- Nc
- Ursa
- Visual Basic .NET
- Wren
- X86 Assembly
- X86-64 Assembly
- Zkl
- Zsh
- ACL2/Omit
- Applesoft BASIC/Omit
- Batch File/Omit
- GUISS/Omit
- Integer BASIC/Omit
- Lotus 123 Macro Scripting/Omit
- Locomotive Basic/Omit
- Maxima/Omit
- ML/I/Omit
- PARI/GP/Omit
- Retro/Omit
- TI-83 BASIC/Omit
- TI-89 BASIC/Omit
- Yorick/Omit
- ZX Spectrum Basic/Omit