Skip to content

Instantly share code, notes, and snippets.

@chaosx
Last active September 20, 2017 06:48
Show Gist options
  • Select an option

  • Save chaosx/4df95e96fced1e4c9aae3842afa55fc5 to your computer and use it in GitHub Desktop.

Select an option

Save chaosx/4df95e96fced1e4c9aae3842afa55fc5 to your computer and use it in GitHub Desktop.
Basic socket programming
package main
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
)
func main(){
msg := getMessage()
res, err := tcpClient(msg)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(res)
}
func getMessage() []byte {
msg := []byte("hello message")
// get msg length
l := uint32(len(msg))
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, l)
// merge
p := bytesCombine(b, msg)
return p
}
func bytesCombine(pBytes ...[]byte) []byte {
return bytes.Join(pBytes, []byte(""))
}
func tcpClient(address string, message []byte) ([]byte, error) {
servAddr := address + ":2222"
reply := make([]byte, 1024)
tcpAddr, err := net.ResolveTCPAddr("tcp", servAddr)
if err != nil {
return reply, errors.New("ResolveTCPAddr failed:" + err.Error())
}
conn, err := net.DialTCP("tcp", nil, tcpAddr)
if err != nil {
return reply, errors.New("Dial failed:" + err.Error())
}
defer conn.Close()
_, err = conn.Write(message)
if err != nil {
return reply, errors.New("Write to server failed:" + err.Error())
}
result, err := ioutil.ReadAll(conn)
if err != nil {
return reply, errors.New("Read to server failed:" + err.Error())
}
data_length := binary.BigEndian.Uint32(result[0:4])
data := result[4:]
return data, nil
}
import struct
import asyncio
@asyncio.coroutine
def handle_echo(reader, writer):
message = yield from recv_msg(reader)
addr = writer.get_extra_info('peername')
yield from send_msg(writer, message)
yield from writer.drain()
writer.close()
async def send_msg(sock, msg):
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.write(msg)
async def recv_msg(sock):
# Read message length and unpack it into an integer
raw_msglen = await _recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return await _recvall(sock, msglen)
async def _recvall(sock, n):
# Helper function to recv n bytes or return None if EOF is hit
data = b''
while len(data) < n:
packet = await sock.read(n - len(data))
if not packet:
return None
data += packet
return data
class Server(object):
if sys.platform == "win32":
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
else:
loop = asyncio.get_event_loop()
server = None
def start(self):
coro = asyncio.start_server(handle_echo, '0.0.0.0', 2222, loop=self.loop)
self.server = self.loop.run_until_complete(coro)
self.loop.run_forever()
def stop(self):
# Close the server
self.server.close()
self.loop.run_until_complete(self.server.wait_closed())
self.loop.close()
if __name__ == '__main__':
s = Server()
s.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment