I'm trying to build a ISO8583 Client using a Golang, when using java, i don't have any problem when creating client. But when trying creating a client using golang (i'm just starting learning golang btw), i can't send a message to the server. Can someone help me, why i can't send a message?
I've tried to send a SIGN IN Message, The client and server already connected, but the message i send not readable by the server.
This My Code
package main
import (
"bufio"
"fmt"
"net"
"os"
"time"
"github.com/ideazxy/iso8583"
)
type ISOSignIn struct {
Bit3 *iso8583.Numeric `field:"3" length:"6" encode:"bcd"`
Bit7 *iso8583.Numeric `field:"7" length:"10" encode:"ascii`
Bit11 *iso8583.Numeric `field:"11" length:"6" encode:"rbcd`
Bit32 *iso8583.Llnumeric `field:"32" length:"11" encode:"ascii`
Bit70 *iso8583.Numeric `field:"70" length:"3" encode:"ascii`
}
func main() {
testIso()
}
func testIso() {
data := ISOSignIn{
Bit3: iso8583.NewNumeric("001111"),
Bit7: iso8583.NewNumeric("0913110004"),
Bit11: iso8583.NewNumeric("000001"),
Bit32: iso8583.NewLlnumeric("9999"), // Client ID
Bit70: iso8583.NewNumeric("301"), // Login Code
}
msg := iso8583.NewMessage("0800", data)
msg.MtiEncode = iso8583.BCD
b, err := msg.Bytes()
if err != nil {
fmt.Println(err.Error())
}
fmt.Printf("% x
", b)
tcpClientNew(b)
}
func tcpClientNew(b []byte) {
tcpAddr, err := net.ResolveTCPAddr("tcp", "192.168.100.5:12346")
if err != nil {
println("ResolveTCPAddr failed:", err.Error())
os.Exit(1)
}
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
println("Dial failed:", err.Error())
os.Exit(1)
}
timeoutDuration := 30 * time.Second
_, err = conn.Write(b)
if err != nil {
println("Write to server failed:", err.Error())
os.Exit(1)
}
conn.SetReadDeadline(time.Now().Add(timeoutDuration))
bufReader := bufio.NewReader(conn)
resp, _ := bufReader.ReadByte()
fmt.Print("Message from server: " + string(resp))
conn.Close()
}
Server Already Connected
<log realm="Server-A.server.session/192.168.100.1:32218" at="Mon Jan 07 09:37:15.747 WIB 2019">
<session-start/>
</log>
<log realm="channel/192.168.100.1:32218" at="Mon Jan 07 09:37:19.034 WIB 2019" lifespan="3287ms">
<receive>
<peer-disconnect/>
</receive>
</log>
<log realm="Server-A.server.session/192.168.100.1:32218" at="Mon Jan 07 09:37:19.035 WIB 2019">
<session-end/>
</log>
Output from Client Terminal :
GOROOT=/Users/ivanaribanilia/Applications/go
GOPATH=/Users/ivanaribanilia/Project/Workspace-Github/Project-Go/pclient
/Users/ivanaribanilia/Applications/go/bin/go build -i -o /Users/ivanaribanilia/Project/Workspace-Github/Project-Go/pclient/build/pclient /Users/ivanaribanilia/Project/Workspace-Github/Project-Go/pclient/src/github.com/ivanj4u/pclient/main.go
/Users/ivanaribanilia/Project/Workspace-Github/Project-Go/pclient/build/pclient
08 00 22 20 00 01 00 00 00 00 00 11 11 30 39 31 33 31 31 30 30 30 34 30 30 30 30 30 31 30 34 31 31 31 34
Message from server:
Process finished with exit code 0
I expect a response from the server, so i can develop other message like INQUIRY or PAYMENT. Thank you
ReadByte reads and returns a single byte. If no byte is available, returns an error.
seems that what you read from server is only one byte, which is a white-space char.
The server and client should make a protocol when to close the connection. Thus, if server don't close the conn actively, client should read all bytes from server and close the connection. Like this:
recvBuf := make([]byte, 1024)
n, err := bufReader.Read(recvBuf)
for err == nil {
println("Recv data from server:", string(recvBuf[:n]))
n, err = bufReader.Read(recvBuf)
}
if err != io.EOF {
println("recv from server failed, err:", err)
}
conn.Close()
Or if the protocol defines the client should close the connection when received a certain byte, client can use ReadBytes() and close the connection actively.
func (b *Reader) ReadBytes(delim byte) ([]byte, error)
ReadBytes reads until the first occurrence of delim in the input, returning a slice containing the data up to and including the delimiter. If ReadBytes encounters an error before finding a delimiter, it returns the data read before the error and the error itself (often io.EOF). ReadBytes returns err != nil if and only if the returned data does not end in delim.