Skip to content

Commit 7182a32

Browse files
committed
add client connect timeout func
1 parent efb315c commit 7182a32

File tree

2 files changed

+247
-220
lines changed

2 files changed

+247
-220
lines changed

tcpclient/client.go

Lines changed: 143 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,167 @@
11
package tcpclient
22

33
import (
4-
"fmt"
5-
"io"
6-
"net"
4+
"fmt"
5+
"io"
6+
"net"
7+
"time"
78
)
89

910
// connect to remote server
1011
func connectToServer(ip string, port uint16, cli *CtcpCli) error {
11-
// const ftag = "connectToServer()"
12+
// const ftag = "connectToServer()"
1213

13-
svrAddr := fmt.Sprintf("%s:%d", ip, port)
14-
conn, err := net.Dial("tcp", svrAddr)
15-
if nil != err {
16-
return err
17-
}
14+
svrAddr := fmt.Sprintf("%s:%d", ip, port)
15+
conn, err := net.Dial("tcp", svrAddr)
16+
if nil != err {
17+
return err
18+
}
1819

19-
cliNewConnection(conn, ip, port, cli)
20+
cliNewConnection(conn, ip, port, cli)
2021

21-
go cliLoopRead(conn, ip, port, cli, cli.cnf.AsyncReceive)
22-
go cliLoopSend(conn, ip, port, cli.chMsgsToBeSend, cli,
23-
cli.cnf.RequireSendedCb, cli.cnf.AsyncSended)
22+
go cliLoopRead(conn, ip, port, cli, cli.cnf.AsyncReceive)
23+
go cliLoopSend(conn, ip, port, cli.chMsgsToBeSend, cli,
24+
cli.cnf.RequireSendedCb, cli.cnf.AsyncSended)
2425

25-
return nil
26+
return nil
27+
}
28+
29+
// connect to remote server
30+
func connectToServer_Timeout(ip string, port uint16, timeout time.Duration,
31+
cli *CtcpCli) error {
32+
// const ftag = "connectToServer()"
33+
34+
svrAddr := fmt.Sprintf("%s:%d", ip, port)
35+
conn, err := net.DialTimeout("tcp", svrAddr, timeout)
36+
if nil != err {
37+
return err
38+
}
39+
40+
cliNewConnection(conn, ip, port, cli)
41+
42+
go cliLoopRead(conn, ip, port, cli, cli.cnf.AsyncReceive)
43+
go cliLoopSend(conn, ip, port, cli.chMsgsToBeSend, cli,
44+
cli.cnf.RequireSendedCb, cli.cnf.AsyncSended)
45+
46+
return nil
2647
}
2748

2849
func closeCliConn(conn net.Conn, ip string, port uint16, cli *CtcpCli) {
29-
conn.Close()
50+
conn.Close()
3051

31-
// notify upper handler
32-
cliDisconnected(ip, port, cli)
52+
// notify upper handler
53+
cliDisconnected(ip, port, cli)
3354
}
3455

3556
// loop read for one client
3657
func cliLoopRead(conn net.Conn, ip string, port uint16,
37-
cli *CtcpCli, asyncReceive bool) {
38-
const ftag = "cliLoopRead()"
39-
40-
defer closeCliConn(conn, ip, port, cli)
41-
42-
var (
43-
allbuf = make([]byte, 0)
44-
buffer = make([]byte, 4096)
45-
byAfterDepackBuff []byte
46-
lenRcv int
47-
err error
48-
)
49-
50-
for {
51-
lenRcv, err = conn.Read(buffer)
52-
53-
if nil != err {
54-
select {
55-
case <-cli.chExit:
56-
// client close
57-
return
58-
59-
default:
60-
}
61-
62-
if io.EOF == err {
63-
errMsgTmp := fmt.Sprintf("%v read from connect EOF, server IP:%s, port:%d", ftag, ip, port)
64-
cli.handler.OnErrorStr(errMsgTmp)
65-
break
66-
} else {
67-
errMsgTmp := fmt.Sprintf("%v read from connect failed, server IP:%s, port:%d", ftag, ip, port)
68-
cli.handler.OnError(errMsgTmp, err)
69-
break
70-
}
71-
}
72-
73-
if 0 == lenRcv {
74-
continue
75-
}
76-
77-
allbuf = append(allbuf, buffer[:lenRcv]...)
78-
byAfterDepackBuff = cliDataRcved(ip, port, lenRcv, allbuf, cli, asyncReceive)
79-
allbuf = byAfterDepackBuff
80-
}
81-
82-
// fmt.Printf("%v end loop of client read, server IP:%v, port:%v\n", ftag, ip, port)
58+
cli *CtcpCli, asyncReceive bool) {
59+
const ftag = "cliLoopRead()"
60+
61+
defer closeCliConn(conn, ip, port, cli)
62+
63+
var (
64+
allbuf = make([]byte, 0)
65+
buffer = make([]byte, 4096)
66+
byAfterDepackBuff []byte
67+
lenRcv int
68+
err error
69+
)
70+
71+
for {
72+
lenRcv, err = conn.Read(buffer)
73+
74+
if nil != err {
75+
select {
76+
case <-cli.chExit:
77+
// client close
78+
return
79+
80+
default:
81+
}
82+
83+
if io.EOF == err {
84+
errMsgTmp := fmt.Sprintf("%v read from connect EOF, server IP:%s, port:%d", ftag, ip, port)
85+
cli.handler.OnErrorStr(errMsgTmp)
86+
break
87+
} else {
88+
errMsgTmp := fmt.Sprintf("%v read from connect failed, server IP:%s, port:%d", ftag, ip, port)
89+
cli.handler.OnError(errMsgTmp, err)
90+
break
91+
}
92+
}
93+
94+
if 0 == lenRcv {
95+
continue
96+
}
97+
98+
allbuf = append(allbuf, buffer[:lenRcv]...)
99+
byAfterDepackBuff = cliDataRcved(ip, port, lenRcv, allbuf, cli, asyncReceive)
100+
allbuf = byAfterDepackBuff
101+
}
102+
103+
// fmt.Printf("%v end loop of client read, server IP:%v, port:%v\n", ftag, ip, port)
83104
}
84105

85106
// loop send for client send
86107
func cliLoopSend(conn net.Conn, ip string, port uint16,
87-
chMsgsToBeSend <-chan interface{}, cli *CtcpCli,
88-
requireSendedCb bool, asyncSended bool) {
89-
const ftag = "cliLoopSend()"
90-
91-
var (
92-
bysTobeSend []byte
93-
dumyBys = make([]byte, 0)
94-
msg interface{}
95-
ok bool
96-
length int
97-
err error
98-
)
99-
100-
for {
101-
bysTobeSend = dumyBys
102-
103-
select {
104-
case <-cli.chExit:
105-
// client close
106-
//fmt.Printf("%v closing of client chExit-1, ip:%s, port:%d\n", ftag, ip, port)
107-
cli.handler.OnEvent("cliLoopSend() exit because exit signal")
108-
return
109-
110-
case msg, ok = <-chMsgsToBeSend:
111-
if !ok {
112-
cli.handler.OnEvent("cliLoopSend() exit because send channel closed")
113-
return
114-
}
115-
}
116-
117-
bysTobeSend, err = cli.handler.Pack(msg)
118-
if nil != err {
119-
cli.handler.OnError("pack failed", err)
120-
continue
121-
} else if nil == bysTobeSend {
122-
cli.handler.OnErrorStr("empty []byte to send")
123-
continue
124-
}
125-
126-
length, err = conn.Write(bysTobeSend)
127-
if nil != err {
128-
select {
129-
case <-cli.chExit:
130-
// client close
131-
//fmt.Printf("%v closing of client chExit-3, ip:%s, port:%d\n", ftag, ip, port)
132-
return
133-
134-
default:
135-
}
136-
137-
errMsgTmp := fmt.Sprintf("write failed, msg=%v", msg)
138-
cli.handler.OnError(errMsgTmp, err)
139-
continue
140-
}
141-
142-
cliDataSended(ip, port, msg, bysTobeSend, length, cli, requireSendedCb, asyncSended)
143-
}
144-
145-
//fmt.Printf("%v end loop of client send, ip:%s, port:%d\n", ftag, ip, port)
108+
chMsgsToBeSend <-chan interface{}, cli *CtcpCli,
109+
requireSendedCb bool, asyncSended bool) {
110+
// const ftag = "cliLoopSend()"
111+
112+
var (
113+
bysTobeSend []byte
114+
dumyBys = make([]byte, 0)
115+
msg interface{}
116+
ok bool
117+
length int
118+
err error
119+
)
120+
121+
for {
122+
bysTobeSend = dumyBys
123+
124+
select {
125+
case <-cli.chExit:
126+
// client close
127+
//fmt.Printf("%v closing of client chExit-1, ip:%s, port:%d\n", ftag, ip, port)
128+
cli.handler.OnEvent("cliLoopSend() exit because exit signal")
129+
return
130+
131+
case msg, ok = <-chMsgsToBeSend:
132+
if !ok {
133+
cli.handler.OnEvent("cliLoopSend() exit because send channel closed")
134+
return
135+
}
136+
}
137+
138+
bysTobeSend, err = cli.handler.Pack(msg)
139+
if nil != err {
140+
cli.handler.OnError("pack failed", err)
141+
continue
142+
} else if nil == bysTobeSend {
143+
cli.handler.OnErrorStr("empty []byte to send")
144+
continue
145+
}
146+
147+
length, err = conn.Write(bysTobeSend)
148+
if nil != err {
149+
select {
150+
case <-cli.chExit:
151+
// client close
152+
//fmt.Printf("%v closing of client chExit-3, ip:%s, port:%d\n", ftag, ip, port)
153+
return
154+
155+
default:
156+
}
157+
158+
errMsgTmp := fmt.Sprintf("write failed, msg=%v", msg)
159+
cli.handler.OnError(errMsgTmp, err)
160+
continue
161+
}
162+
163+
cliDataSended(ip, port, msg, bysTobeSend, length, cli, requireSendedCb, asyncSended)
164+
}
165+
166+
//fmt.Printf("%v end loop of client send, ip:%s, port:%d\n", ftag, ip, port)
146167
}

0 commit comments

Comments
 (0)