任务一:创建客户端和服务器端进行消息的传递和确认
- TCP服务器创建后,监听所有计算机内部地址,一旦有连接请求,就停止监听,进行数据接收。并返回“ACK”
- TCP客户端则尝试连接服务器端,并发送数据
TCP客户端的创建
- 创建一个
socket
对象,参数AF_INET
表示Internet,SCOK_STREAM
表示面向连接的TCP。
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
客户端连接到服务器,使用connect
函数,参数为IP地址与端口号:
client.connect((target_host,target_port))
发送数据,使用send
函数:
client.send("Hello world")
按照每次4096字节的规则接收服务器的数据并打印:
response = client.recv(4096)
print response
整个流程:
创建套接字、连接服务器、发送消息、接受回信。
TCP服务器端的创建
socket对象建立。‘
作为服务器需要有一个IP地址和端口号,使用bind
函数将这两个信息绑定给刚刚定义的socket:
server.bind(bind_ip,bind_port)
服务器开始监听:
server.listen(5)
关于listen函数的解释:
There is no buffer that the application monitors. Instead, the application calls listen() at some point, and the OS remembers from then on that this application is interested in new connections to that port number. Only one application can indicate interest in a certain port at any time.
同一时刻,只可能有一个应用获得监听某个端口的权限。listen()
告诉系统其对某个端口的连接有兴趣,并记住。
The listen operation does not block. Instead, it returns right away. What may block is
accept()
. The system has a backlog of incoming connections (buffering the data that have been received, and returns one of the connections every time accept is called. accept doesn’t transmit any data; the application must then dorecv()
calls on the accepted socket.
listen()
函数不会阻塞等待,他会立刻返回。accept()
才会阻塞。
首先看accept()
函数:
socket.accept()
Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.
接受一个连接,此时的socket(server)必须是一个已经绑定于某个ip地址和端口的socket了——它在监听某个端口。返回值为一个二元组:(conn, address)。其中,conn是新的socket对象,专用于server和监听对象之间的通信传输,address则是对面的IP地址。因为这里的server监听的是0.0.0.0包含了本机所有的内部ip地址,所以需要知道具体的连接的那一个的ip。
接下来是进行客户端线程的设计。
这里传入的是刚刚accept()创建出的用于传递server和client消息的一个socket。
client首先发消息
#print out what the client sends
request = client_socket.recv(1024)
使用recv()收到消息,打印之。
print "[*] Received: %s" % request
回送一个”ACK”
# send back a packet
client_socket.send("ACK!")
client_socket.close()
从当中可以看到,accept()返回的socket是一个站在server端的socket,它的recv()是从client发来的,它的send是发回给client的。
总体可以概括为: