selfboot / AnnotatedShadowSocks

Annotated shadowsocks(python version)
Other
3 stars 1 forks source link

Socket: TCP/IP Client and Server #13

Open selfboot opened 7 years ago

selfboot commented 7 years ago

Sockets can be configured to act as a server and listen for incoming messages, or connect to other applications as a client. After both ends of a TCP/IP socket are connected, communication is bi-directional.

server and client

Echo Server

This sample program, receives incoming messages and echo them back to the sender.

  1. It starts by creating a TCP/IP socket.
  2. Then bind() is used to associate the socket with the server address. In this case, the address is localhost, referring to the current server, and the port number is 10000.
  3. Calling listen() puts the socket into server mode.
  4. Calling accept() waits for an incoming connection, accept() returns an open connection between the server and client, along with the address of the client. The connection is actually a different socket on another port (assigned by the kernel).
  5. Data is read from the connection with recv() and transmitted with sendall().
  6. When communication with a client is finished, the connection needs to be cleaned up using close().
server.py is here. (click to unfold) ```python #! /usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function import socket import sys # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Bind the socket to the port server_address = ('localhost', 10000) print('starting up on %s port %s' % server_address, file=sys.stdout) sock.bind(server_address) # Listen for incoming connections sock.listen(1) while True: # Wait for a connection print('waiting for a connection', file=sys.stdout) connection, client_address = sock.accept() try: print('connection from', client_address, file=sys.stdout) # Receive the data in small chunks and retransmit it while True: data = connection.recv(16) print('received "%s"' % data, file=sys.stdout) if data: print('sending data back to the client', file=sys.stdout) connection.sendall(data) else: print('no more data from', client_address, file=sys.stderr) break finally: # Clean up the connection connection.close() ```

This example uses a `try:finally` block to ensure that close() is always called, even in the event of an error. ## Echo client The client program sets up its socket differently from the way a server does. Instead of binding to a port and listening, it uses **connect()** to attach the socket directly to the remote address. After the connection is established, data can be sent through the socket with **sendall()** and received with recv(), just as in the server. When the entire message is sent and a copy received, the socket is closed to free up the port.

client.py is here. (click to unfold) ```python #! /usr/bin/env python # -*- coding: utf-8 -*- from __future__ import print_function import socket import sys # Create a TCP/IP socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Connect the socket to the port where the server is listening server_address = ('localhost', 10000) print('connecting to %s port %s' % server_address) sock.connect(server_address) try: # Send data message = 'This is the message. It will be repeated.' print('sending "%s"' % message) sock.sendall(message) # Look for the response amount_received = 0 amount_expected = len(message) while amount_received < amount_expected: data = sock.recv(16) amount_received += len(data) print('received "%s"' % data) finally: print('closing socket') sock.close() ```

The client and server should be run in separate terminal windows, so they can communicate with each other. It is important to bind a server to the correct address, so that clients can communicate with it. The previous examples all used 'localhost' as the IP address, which limits connections to clients running on the same server. Use a public address of the server, such as the value returned by `gethostname()`, to allow other hosts to connect. **Ref**: [TCP/IP Client and Server](https://pymotw.com/2/socket/tcp.html) [What does this code mean: “print >> sys.stderr”](http://stackoverflow.com/questions/1987626/what-does-this-code-mean-print-sys-stderr) https://github.com/xuelangZF/CS_Offer/blob/master/Network/Socket.md