Sockets
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.
You are encouraged to solve this task according to the task description, using any language you may know.
Ada
<lang ada>with GNAT.Sockets; use GNAT.Sockets;
procedure SocketSend is
procedure sendData (IP : String; Msg : String) is Client : Socket_Type; Address : Sock_Addr_Type; Channel : Stream_Access; begin Create_Socket (Client); Address.Addr := Inet_Addr(ip); Address.Port := 256; Connect_Socket (Client, Address); Channel := Stream (Client); String'Write (Channel, Msg); Close_Socket (Client); end;
begin
Initialize; sendData ("127.0.0.1","hello socket world");
end;</lang>
AutoHotkey
modified from script by zed gecko. <lang autohotkey>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</lang>
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 256
.
<lang c>#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); }
}</lang>
C#
<lang csharp>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(); }
}</lang>
Clojure
<lang clojure>(ns socket-example
(:import (java.net Socket) (java.io PrintWriter)))
(defn send-data [host msg]
(let [sock (Socket. host 256) printer (PrintWriter. (.getOutputStream sock))] (.println printer msg) (.close printer) (.close sock)))
(send-data "localhost" "hello socket world")</lang>
Common Lisp
<lang lisp>CL-USER> (usocket:with-client-socket (socket stream "localhost" 256)
(write-line "hello socket world" stream) (values))
- No value</lang>
<lang lisp>aurora ~% sudo nc -l -p 256 hello socket world</lang>
D
<lang 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() {
auto socket = new Socket(AddressFamily.INET, SocketType.STREAM) ; socket.connect(new InternetAddress("localhost",256)) ; writefln(socket.send(cast(void[])"hello socket world"), " bytes sent.") ; socket.close() ;
}</lang>
Factor
<lang factor>"localhost" 256 <inet> utf8 [ "hello socket world" print ] with-client</lang>
Forth
<lang forth>include unix/socket.fs
s" localhost" 256 open-socket
dup s" hello socket world" rot write-socket
close-socket</lang>
Go
<lang go>package main
import "net"
import "fmt"
func main() {
conn, err := net.Dial("tcp", "", "localhost:256") if err != nil { fmt.Println(err) return } conn.Write([]byte("hello socket world")) conn.Close()
}</lang>
Groovy
<lang groovy>s = new java.net.Socket("localhost", 256) s << "hello socket world" s.close()</lang>
Haskell
<lang haskell>import Network
main = withSocketsDo $ sendTo "localhost" (PortNumber $ toEnum 256) "hello socket world"</lang>
Icon and Unicon
Icon
<lang icon>link cfunc procedure main ()
hello("localhost", 1024)
end
procedure hello (host, port)
write(tconnect(host, port) | stop("unable to connect to", host, ":", port) , "hello socket world")
end</lang> Note: Socket support in native Icon is limited and requires the external helper function cfunc.
Unicon
Unicon integrated TCP/IP networking and messaging. <lang unicon>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</lang>
IDL
<lang idl>socket, unit, 'localhost',256,/get_lun printf,unit,"hello socket world" close, unit</lang>
"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:
<lang j> 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</lang>
Java
<lang 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(); }
}</lang>
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.
Lua
Requires: LuaSocket <lang lua>socket = require "socket" host, port = "127.0.0.1", 256
sid = socket.udp() sid:sendto( "hello socket world", host, port ) sid:close()</lang>
Objeck
<lang 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(); } } }
} </lang>
OCaml
<lang 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)</lang>
<lang ocaml>let () =
let ic, oc = init_socket "localhost" 256 in output_string oc "hello socket world";
- </lang>
Oz
<lang oz>declare
Socket = {New Open.socket init}
in
{Socket connect(port:256)} {Socket write(vs:"hello socket world")} {Socket close}</lang>
Perl
<lang 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);</lang>
Object oriented version. <lang perl>use Socket::Class;
$sock = Socket::Class->new(
'remote_port' => 256,
) || die Socket::Class->error; $sock->send('hello socket world'); $sock->free;</lang>
PHP
<lang PHP>$socket = fsockopen('localhost', 256); fputs($socket, 'hello socket world'); fclose($socket);</lang>
PicoLisp
<lang PicoLisp>(when (connect "localhost" 256)
(out @ (prinl "hello socket world")) (close @) )</lang>
Pike
<lang pike>import Stdio;
int main(){
object con = File(); con->connect("127.0.0.1",256); con->write("hello socket world"); con->close();
}</lang>
PureBasic
<lang Purebasic>InitNetwork() ConnectionID = OpenNetworkConnection("localhost", 256) SendNetworkString(ConnectionID, "hello socket world") CloseNetworkConnection(ConnectionID)</lang>
Python
<lang python>import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("localhost", 256)) sock.sendall("hello socket world") sock.close()</lang>
Rhope
<lang rhope>Socket Send(0,0) |:
[New@Net Client["localhost",256]]Put String["hello socket world"]
- |</lang>
The connection is automatically closed when the object is freed.
Ruby
<lang ruby>require 'socket' sock = TCPSocket.open("localhost", 256) sock.write("hello socket world") sock.close</lang>
Seed7
<lang seed7>$ 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;</lang>
Slate
This uses fairly verbose and low level messages. This will probably be simplified in the future.
<lang slate>[ | 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.</lang>
Smalltalk
This is taken from here with few modification to fit the task better.
<lang smalltalk>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.</lang>
Tcl
<lang tcl>set io [socket localhost 256] puts -nonewline $io "hello socket world" close $io</lang>
Toka
<lang 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</lang>
UnixPipes
<lang bash>(echo "hello socket world" | nc localhost 256 | exit 0)</lang>
UNIX Shell
Using the program netcat (nc)
<lang bash>echo "hello socket world" | netcat localhost 256</lang>
Visual Basic .NET
<lang vbnet>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</lang>
X86 Assembly
<lang asm>
- 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 </lang>
Operates in non-blocking mode. <lang asm> .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
</lang>
This example works in blocking mode. <lang asm> .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
</lang>
Zsh
<lang zsh>zmodload zsh/net/tcp ztcp localhost 256 print hello socket world >&$REPLY</lang>