Last active
September 20, 2017 06:48
-
-
Save chaosx/4df95e96fced1e4c9aae3842afa55fc5 to your computer and use it in GitHub Desktop.
Basic socket programming
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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