Add assembler client
This commit is contained in:
parent
7c24814352
commit
24255230c3
|
@ -18,3 +18,11 @@ This is the code used in the [23 Year Old Code](https://youtu.be/l4GNHJfYOUU) vi
|
||||||
prints out what is received, like a very basic `netcat`.
|
prints out what is received, like a very basic `netcat`.
|
||||||
|
|
||||||
This is the code used in the [Simple Server in C for the Commodore Amiga](https://youtu.be/i6_PQUsayN4) video.
|
This is the code used in the [Simple Server in C for the Commodore Amiga](https://youtu.be/i6_PQUsayN4) video.
|
||||||
|
|
||||||
|
## Client in Assembler
|
||||||
|
|
||||||
|
`client_in_asm` uses AsmPro and the AmiTCK SDK to build a simple client that
|
||||||
|
connects to a specified host and port and sends some data, like the other end
|
||||||
|
of a very basic `netcat`.
|
||||||
|
|
||||||
|
This is the code used in the [Building a simple Amiga network client...in assembler?!?](https://youtu.be/HbMPBbF9-RE) video.
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Amiga BSD Socket Client in Assembler and C
|
||||||
|
|
||||||
|
The versions are identical, except that the C version uses `printf` instead
|
||||||
|
of `PutStr()`.
|
||||||
|
|
||||||
|
## Assembler Version
|
||||||
|
|
||||||
|
Built using AsmPro. You'll have to adjust the `INCDIR` locations and build
|
||||||
|
the LVOs for the `bsdsocket` and `dos` libraries. You can get the socket
|
||||||
|
FD file from the AmiTCP SDK.
|
||||||
|
|
||||||
|
```
|
||||||
|
fd2pragma fd/dos.fd to include_i/ special 20
|
||||||
|
fd2pragma fd/socket.fd to include_i/ special 20
|
||||||
|
```
|
||||||
|
|
||||||
|
## C Version
|
||||||
|
|
||||||
|
Built using SAS/C 6.58 and the
|
||||||
|
[AmiTCP 4.3 SDK](http://aminet.net/package/comm/tcp/AmiTCP-SDK-4.3).
|
||||||
|
|
||||||
|
`sc link client.c`
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,400 @@
|
||||||
|
FUNC_CNT SET -30
|
||||||
|
FUNCDEF MACRO
|
||||||
|
_LVO\1 EQU FUNC_CNT
|
||||||
|
FUNC_CNT SET FUNC_CNT-6
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
INCDIR "AsmPro:Include/include_i/"
|
||||||
|
INCLUDE "exec/exec_lib.i"
|
||||||
|
INCLUDE "dos/dos_lvo.i"
|
||||||
|
INCLUDE "exec/libraries.i"
|
||||||
|
INCLUDE "exec/memory.i"
|
||||||
|
INCLUDE "dos/dos.i"
|
||||||
|
INCLUDE "socket_lvo.i"
|
||||||
|
|
||||||
|
PrintString MACRO
|
||||||
|
MOVE.L \1,D1
|
||||||
|
MOVE.L DOSBase,A6
|
||||||
|
CALLLIB _LVOPutStr ; dos/PutStr
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
OpenLibrary MACRO
|
||||||
|
MOVEQ \2,D0
|
||||||
|
MOVE.L \1,A1
|
||||||
|
MOVEA.L 4,A6
|
||||||
|
CALLLIB _LVOOpenLibrary ; exec/OpenLibrary
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
ExitProgram MACRO
|
||||||
|
MOVEQ \1,D0
|
||||||
|
RTS
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
DoCloseDOSLibrary MACRO
|
||||||
|
MOVEA.L DOSBase,A1
|
||||||
|
MOVEA.L 4,A6
|
||||||
|
CALLLIB _LVOCloseLibrary ; exec/CloseLibrary
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
DoCloseBSDSocketLibrary MACRO
|
||||||
|
MOVEA.L BSDSocketBase,A1
|
||||||
|
MOVEA.L 4,A6
|
||||||
|
CALLLIB _LVOCloseLibrary ; exec/CloseLibrary
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
DeallocateBuffer MACRO
|
||||||
|
MOVE.L ReadBuffer,A1
|
||||||
|
MOVE.L #READ_BUFFER_SIZE,D0
|
||||||
|
MOVEA.L 4,A6
|
||||||
|
CALLLIB _LVOFreeMem ; exec/FreeMem
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
DoCloseSocket MACRO
|
||||||
|
MOVE.L SocketID,D0
|
||||||
|
MOVE.L BSDSocketBase,A6
|
||||||
|
CALLLIB _LVOCloseSocket ; bsdsocket/CloseSocket
|
||||||
|
ENDM
|
||||||
|
|
||||||
|
; our user message has a limit of this many characters
|
||||||
|
READ_BUFFER_SIZE EQU 1024
|
||||||
|
|
||||||
|
; bsdsocket library stuff
|
||||||
|
; ported from the various C include headers
|
||||||
|
SOCK_STREAM EQU 1
|
||||||
|
PF_INET EQU 2
|
||||||
|
AF_INET EQU PF_INET
|
||||||
|
IPPROTO_TCP EQU 6
|
||||||
|
|
||||||
|
len_sockaddr_in EQU 16
|
||||||
|
sockaddr_in_sin_len EQU 0
|
||||||
|
sockaddr_in_sin_family EQU 1
|
||||||
|
sockaddr_in_sin_port EQU 2
|
||||||
|
sockaddr_in_sin_addr EQU 4
|
||||||
|
|
||||||
|
Start:
|
||||||
|
OpenLibrary #DOSLibrary,#36
|
||||||
|
MOVE.L D0,DOSBase
|
||||||
|
TST.L D0
|
||||||
|
BNE OpenBSDSocketLibrary
|
||||||
|
|
||||||
|
; if this fails, we have bigger problems
|
||||||
|
MOVE.L #20,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
OpenBSDSocketLibrary:
|
||||||
|
OpenLibrary #BSDSocketLibrary,#4
|
||||||
|
MOVE.L D0,BSDSocketBase
|
||||||
|
TST.L D0
|
||||||
|
BNE ReserveBuffer
|
||||||
|
|
||||||
|
PrintString #UnableToOpenBSDSocketLibrary
|
||||||
|
|
||||||
|
; be sure to unwind everything we've opened so far
|
||||||
|
; i tried using this with codewatcher and i think there's
|
||||||
|
; something up with trying to read command line argument
|
||||||
|
; when run under codewatcher.
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
ReserveBuffer:
|
||||||
|
MOVE.L #READ_BUFFER_SIZE,D0
|
||||||
|
; we don't care where the memory comes from
|
||||||
|
; nor should we!
|
||||||
|
MOVE.L #MEMF_CLEAR,D1
|
||||||
|
MOVEA.L 4,A6
|
||||||
|
CALLLIB _LVOAllocMem ; dos/AllocMem
|
||||||
|
MOVE.L D0,ReadBuffer
|
||||||
|
TST.L D0
|
||||||
|
BNE ReadIPAddress
|
||||||
|
|
||||||
|
PrintString #UnableToAllocateBuffer
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
ReadIPAddress:
|
||||||
|
MOVE.L ReadBuffer,D1
|
||||||
|
MOVE.L #READ_BUFFER_SIZE,D2
|
||||||
|
MOVEQ #0,D3
|
||||||
|
MOVE.L DOSBase,A6
|
||||||
|
CALLLIB _LVOReadItem ; dos/ReadItem
|
||||||
|
|
||||||
|
; fail on an error or a missing parameter
|
||||||
|
CMP.L #ITEM_ERROR,D0
|
||||||
|
BEQ NoIPAddress
|
||||||
|
CMP.L #ITEM_NOTHING,D0
|
||||||
|
BEQ NoIPAddress
|
||||||
|
|
||||||
|
BRA ParseIPAddress
|
||||||
|
|
||||||
|
NoIPAddress:
|
||||||
|
PrintString #UnableToReadArguments
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
ParseIPAddress:
|
||||||
|
MOVE.L ReadBuffer,A0
|
||||||
|
MOVE.L BSDSocketBase,A6
|
||||||
|
CALLLIB _LVOinet_addr ; bsdsocket/inet_addr
|
||||||
|
MOVE.L D0,IPAddress
|
||||||
|
|
||||||
|
TST.L D0
|
||||||
|
BNE ReadPort
|
||||||
|
|
||||||
|
PrintString #UnableToParseIPAddress
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
ReadPort:
|
||||||
|
MOVE.L ReadBuffer,D1
|
||||||
|
MOVE.L #READ_BUFFER_SIZE,D2
|
||||||
|
MOVEQ #0,D3
|
||||||
|
MOVE.L DOSBase,A6
|
||||||
|
CALLLIB _LVOReadItem ; dos/ReadItem
|
||||||
|
|
||||||
|
; fail on an error or a missing parameter
|
||||||
|
CMP.L #ITEM_ERROR,D0
|
||||||
|
BEQ NoPort
|
||||||
|
CMP.L #ITEM_NOTHING,D0
|
||||||
|
BEQ NoPort
|
||||||
|
|
||||||
|
BRA ParsePort
|
||||||
|
|
||||||
|
NoPort:
|
||||||
|
PrintString #UnableToReadArguments
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
|
||||||
|
ParsePort:
|
||||||
|
; the Amiga library way to do atol()
|
||||||
|
MOVE.L ReadBuffer,D1
|
||||||
|
MOVE.L #PortLong,D2
|
||||||
|
MOVE.L DOSBase,A6
|
||||||
|
CALLLIB _LVOStrToLong ; dos/StrToLong
|
||||||
|
|
||||||
|
CMP.L #-1,D0
|
||||||
|
BNE _ParsePort_Continue
|
||||||
|
|
||||||
|
PrintString #UnableToParsePort
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
_ParsePort_Continue:
|
||||||
|
MOVE.L PortLong,D0
|
||||||
|
|
||||||
|
; we could just crop the provided port at a word boundary,
|
||||||
|
; but let's be nice and tell the user they entered in a bad
|
||||||
|
; port number.
|
||||||
|
CMP.L #65536,D0
|
||||||
|
BLT ReadRemainingCommandLine
|
||||||
|
|
||||||
|
PrintString #PortOutOfRange
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
ReadRemainingCommandLine:
|
||||||
|
; lop off the actual port number
|
||||||
|
MOVE.W D0,Port
|
||||||
|
|
||||||
|
; this is the Amiga equivalent of stdin?
|
||||||
|
MOVE.L DOSBase,A6
|
||||||
|
CALLLIB _LVOInput ; dos/Input
|
||||||
|
MOVE.L D0,Stdin
|
||||||
|
|
||||||
|
MOVE.L ReadBuffer,FGetCLocation
|
||||||
|
MOVEQ #0,D2
|
||||||
|
|
||||||
|
_ReadRemainingCommandLine_Loop:
|
||||||
|
; loop until fgetc returns -1 or 10
|
||||||
|
MOVE.L Stdin,D1
|
||||||
|
MOVE.L DOSBase,A6
|
||||||
|
CALLLIB _LVOFGetC ; dos/FGetC
|
||||||
|
|
||||||
|
MOVE.L FGetCLocation,A0
|
||||||
|
CMP.L #-1,D0 ; end on EOF...
|
||||||
|
BEQ _ReadRemainingCommandLine_Finish
|
||||||
|
CMP.L #10,D0 ; or a 10, from you physically hitting enter in the CLI
|
||||||
|
BEQ _ReadRemainingCommandLine_Finish
|
||||||
|
|
||||||
|
MOVE.B D0,(A0)+
|
||||||
|
ADDQ #1,D2
|
||||||
|
MOVE.L A0,FGetCLocation
|
||||||
|
BRA _ReadRemainingCommandLine_Loop
|
||||||
|
|
||||||
|
_ReadRemainingCommandLine_Finish:
|
||||||
|
; add the chr(10) back, and end the string with a null
|
||||||
|
MOVE.B #10,(A0)+
|
||||||
|
MOVE.B #0,(A0)+
|
||||||
|
|
||||||
|
; we need to know how many characters total we read
|
||||||
|
ADDQ #2,D2
|
||||||
|
MOVE.L D2,ReadBufferLength
|
||||||
|
|
||||||
|
CreateSocket:
|
||||||
|
MOVE.L #PF_INET,D0
|
||||||
|
MOVE.L #SOCK_STREAM,D1
|
||||||
|
MOVE.L #IPPROTO_TCP,D2
|
||||||
|
MOVE.L BSDSocketBase,A6
|
||||||
|
CALLLIB _LVOsocket ; exec/socket
|
||||||
|
MOVE.L D0,SocketID
|
||||||
|
|
||||||
|
PrintIPAddress:
|
||||||
|
; exec/RawDoFmt is basically sprintf.
|
||||||
|
LEA IPAddrString,A0
|
||||||
|
|
||||||
|
; load up the printf arguments
|
||||||
|
LEA DoFmtBuffer,A1
|
||||||
|
MOVE.L IPAddress,(A1)+
|
||||||
|
MOVE.W Port,(A1)+
|
||||||
|
MOVE.L SocketID,(A1)+
|
||||||
|
LEA DoFmtBuffer,A1
|
||||||
|
|
||||||
|
LEA _StuffChar,A2
|
||||||
|
LEA PrintBuffer,A3
|
||||||
|
|
||||||
|
MOVE.L 4,A6
|
||||||
|
CALLLIB _LVORawDoFmt ; exec/RawDoFmt
|
||||||
|
|
||||||
|
PrintString #PrintBuffer
|
||||||
|
|
||||||
|
MOVE.L SocketID,D0
|
||||||
|
CMP.L #-1,D0
|
||||||
|
BNE ConnectSocket
|
||||||
|
|
||||||
|
PrintString #UnableToOpenSocket
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
ConnectSocket:
|
||||||
|
; populate sockaddr_in
|
||||||
|
LEA ConnectSockAddrIn,A0
|
||||||
|
MOVE.B #AF_INET,sockaddr_in_sin_family(A0)
|
||||||
|
MOVE.W Port,sockaddr_in_sin_port(A0)
|
||||||
|
MOVE.L IPAddress,sockaddr_in_sin_addr(A0)
|
||||||
|
|
||||||
|
MOVE.L SocketID,D0
|
||||||
|
MOVE.L #len_sockaddr_in,D1
|
||||||
|
MOVE.L BSDSocketBase,A6
|
||||||
|
CALLLIB _LVOconnect ; bsdsocket/connect
|
||||||
|
|
||||||
|
; a socket is connected if the response is 0
|
||||||
|
TST.L D0
|
||||||
|
BEQ SendData
|
||||||
|
|
||||||
|
PrintString #UnableToConnectSocket
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
SendData:
|
||||||
|
MOVE.L SocketID,D0
|
||||||
|
MOVE.L ReadBuffer,A0
|
||||||
|
MOVE.L ReadBufferLength,D1
|
||||||
|
MOVEQ #0,D2
|
||||||
|
MOVE.L BSDSocketBase,A6
|
||||||
|
CALLLIB _LVOsend ; bsdsocket/send
|
||||||
|
|
||||||
|
CMP.L #-1,D0
|
||||||
|
BNE CloseSocket
|
||||||
|
|
||||||
|
PrintString #UnableToSendData
|
||||||
|
|
||||||
|
MOVE.L #1,ExitCode
|
||||||
|
BRA Teardown
|
||||||
|
|
||||||
|
CloseSocket:
|
||||||
|
MOVE.L #0,ExitCode
|
||||||
|
|
||||||
|
; check all of the things we might have allocated and
|
||||||
|
; tear them down if we did, then return the appropriate exit code.
|
||||||
|
Teardown:
|
||||||
|
MOVE.L SocketID,D0
|
||||||
|
CMP.L #-1,D0
|
||||||
|
BEQ _Teardown_DeallocateBuffer
|
||||||
|
|
||||||
|
DoCloseSocket
|
||||||
|
_Teardown_DeallocateBuffer:
|
||||||
|
MOVE.L ReadBuffer,D0
|
||||||
|
BEQ _Teardown_CloseBSDSocketLibrary
|
||||||
|
|
||||||
|
DeallocateBuffer
|
||||||
|
_Teardown_CloseBSDSocketLibrary:
|
||||||
|
MOVE.L BSDSocketBase,D0
|
||||||
|
BEQ _Teardown_CloseDOSLibrary
|
||||||
|
|
||||||
|
DoCloseBSDSocketLibrary
|
||||||
|
_Teardown_CloseDOSLibrary:
|
||||||
|
MOVE.L DOSBase,D0
|
||||||
|
BEQ _Teardown_Exit
|
||||||
|
|
||||||
|
DoCloseDOSLibrary
|
||||||
|
_Teardown_Exit:
|
||||||
|
MOVEQ #0,D0
|
||||||
|
MOVE.L ExitCode,D0
|
||||||
|
RTS
|
||||||
|
|
||||||
|
; RawDoFmt helper
|
||||||
|
_StuffChar:
|
||||||
|
MOVE.B D0,(a3)+
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|
||||||
|
; libraries we open
|
||||||
|
DOSBase DCB.L 1,0
|
||||||
|
BSDSocketBase DCB.L 1,0
|
||||||
|
|
||||||
|
; allocated memory
|
||||||
|
ReadBuffer DCB.L 1,0
|
||||||
|
ReadBufferLength DS.L 1
|
||||||
|
|
||||||
|
; return code for the program
|
||||||
|
ExitCode DS.L 1
|
||||||
|
|
||||||
|
; reading command line args
|
||||||
|
Stdin DS.L 1
|
||||||
|
|
||||||
|
; user parameters
|
||||||
|
IPAddress DS.L 1
|
||||||
|
Port DS.W 1
|
||||||
|
PortLong DS.L 1
|
||||||
|
|
||||||
|
; message to send
|
||||||
|
FGetCChar DS.L 1
|
||||||
|
FGetCLocation DS.L 1
|
||||||
|
|
||||||
|
; establishing a connection
|
||||||
|
SocketID DCB.L 1,-1
|
||||||
|
ConnectSockAddrIn DCB.B 16,0
|
||||||
|
|
||||||
|
; place to build a string for printing via RawDoFmt
|
||||||
|
PrintBuffer DS.B 100
|
||||||
|
|
||||||
|
; stack for accepting RawDoFmt arguments as values
|
||||||
|
DoFmtBuffer DS.B 32
|
||||||
|
|
||||||
|
DOSLibrary DC.B "dos.library",0
|
||||||
|
BSDSocketLibrary DC.B "bsdsocket.library",0
|
||||||
|
|
||||||
|
;FakeIP DC.B "1.2.3.4",0
|
||||||
|
;FakePort DC.B "1234",0
|
||||||
|
|
||||||
|
; user messages
|
||||||
|
UnableToOpenBSDSocketLibrary DC.B "Unable to open bsdsocket.library. Have you started a TCP stack?",10,0
|
||||||
|
UnableToAllocateBuffer DC.B "Unable to allocate buffer",10,0
|
||||||
|
UnableToReadArguments DC.B "client <ip address> <port> <message...>",10,0
|
||||||
|
UnableToParseIPAddress DC.B "Unable to parse IP Address",10,0
|
||||||
|
UnableToOpenSocket DC.B "Unable to open socket",10,0
|
||||||
|
UnableToConnectSocket DC.B "Unable to connect socket",10,0
|
||||||
|
UnableToSendData DC.B "Unable to send data",10,0
|
||||||
|
UnableToParsePort DC.B "Unable to parse port",10,0
|
||||||
|
PortOutOfRange DC.B "Port out of range (0-65535)",10,0
|
||||||
|
;Here DC.B "Here",10,0
|
||||||
|
IPAddrString DC.B "IP address is %8lx, port is %d, socket is %ld",10,0
|
||||||
|
;FGetCResult DC.B "%ld %ld %ld",10,0
|
|
@ -0,0 +1,145 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <strings.h>
|
||||||
|
|
||||||
|
#include <proto/exec.h>
|
||||||
|
#include <proto/dos.h>
|
||||||
|
|
||||||
|
#include <exec/memory.h>
|
||||||
|
|
||||||
|
#include <proto/socket.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
struct Library *SocketBase;
|
||||||
|
char *ReadBuffer;
|
||||||
|
int SocketID = -1;
|
||||||
|
|
||||||
|
#define READ_BUFFER_SIZE (1024)
|
||||||
|
|
||||||
|
void teardown() {
|
||||||
|
if (SocketBase && SocketID != -1) {
|
||||||
|
CloseSocket(SocketID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReadBuffer) {
|
||||||
|
FreeMem(ReadBuffer, READ_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SocketBase) {
|
||||||
|
CloseLibrary(SocketBase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int ReadItemResult;
|
||||||
|
ULONG IPAddress;
|
||||||
|
long Port;
|
||||||
|
char CurrentChar;
|
||||||
|
int ReadIndex;
|
||||||
|
BPTR Stdin;
|
||||||
|
|
||||||
|
struct sockaddr_in ConnectSockaddrIn;
|
||||||
|
|
||||||
|
if (!(SocketBase = OpenLibrary("bsdsocket.library", 4))) {
|
||||||
|
printf("Unable to open bsdsocket.library. Have you started a TCP stack?\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ReadBuffer = AllocMem(READ_BUFFER_SIZE, MEMF_CLEAR))) {
|
||||||
|
printf("Unable to allocate buffer\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// yes we could use argc/argv but we're mimicking what's in the
|
||||||
|
// original assembler code
|
||||||
|
|
||||||
|
ReadItemResult = ReadItem(ReadBuffer, READ_BUFFER_SIZE, NULL);
|
||||||
|
if (
|
||||||
|
ReadItemResult == ITEM_ERROR ||
|
||||||
|
ReadItemResult == ITEM_NOTHING
|
||||||
|
) {
|
||||||
|
printf("client <ip address> <port> <message...>\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(IPAddress = inet_addr(ReadBuffer))) {
|
||||||
|
printf("Unable to parse IP Address\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadItemResult = ReadItem(ReadBuffer, READ_BUFFER_SIZE, NULL);
|
||||||
|
if (
|
||||||
|
ReadItemResult == ITEM_ERROR ||
|
||||||
|
ReadItemResult == ITEM_NOTHING
|
||||||
|
) {
|
||||||
|
printf("client <ip address> <port> <message...>\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-1 == (StrToLong(ReadBuffer, &Port))) {
|
||||||
|
printf("client <ip address> <port> <message...>\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Port > 65535) {
|
||||||
|
printf("Port out of range (0-65535)\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Stdin = Input();
|
||||||
|
|
||||||
|
Port = (short)Port;
|
||||||
|
CurrentChar = FGetC(Stdin);
|
||||||
|
ReadIndex = 0;
|
||||||
|
|
||||||
|
while (CurrentChar != -1 && CurrentChar != 10) {
|
||||||
|
ReadBuffer[ReadIndex++] = CurrentChar;
|
||||||
|
printf("%d\n",CurrentChar);
|
||||||
|
CurrentChar = FGetC(Stdin);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadBuffer[ReadIndex++] = 10;
|
||||||
|
ReadBuffer[ReadIndex++] = 0;
|
||||||
|
|
||||||
|
SocketID = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
|
// we'll skip on using RawDoFmt here
|
||||||
|
printf(
|
||||||
|
"IP address is %8x, port is %d, socket is %d\n",
|
||||||
|
IPAddress,
|
||||||
|
Port,
|
||||||
|
SocketID
|
||||||
|
);
|
||||||
|
|
||||||
|
if (SocketID == -1) {
|
||||||
|
printf("Unable to open socket\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectSockaddrIn.sin_family = AF_INET;
|
||||||
|
ConnectSockaddrIn.sin_port = Port;
|
||||||
|
ConnectSockaddrIn.sin_addr.s_addr = IPAddress;
|
||||||
|
|
||||||
|
if (connect(SocketID, (struct sockaddr *)&ConnectSockaddrIn, sizeof(struct sockaddr_in)) == -1) {
|
||||||
|
printf("Unable to connect socket\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (send(SocketID, ReadBuffer, ReadIndex, 0) == -1) {
|
||||||
|
printf("Unable to send data\n");
|
||||||
|
teardown();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue