根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。 (1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。 (2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。 (3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
在建立通信连接的每一端,进程间的传输要有两个标志:
IP地址和端口号,合称为套接字地址socket address
客户机套接字地址定义了一个唯一的客户进程
服务器套接字地址定义了一个唯一的服务器进程
套接字地址 172.18.0.18:80
名字 | 含义 | 名字 | 含义 |
---|---|---|---|
socket() | 创建一个套接字 | bind() | 绑定IP和端口 |
listen() | 监听 | accept() | 接收请求 |
connect() | 请求连接建立 | write() | 发送 |
read() | 接收 | close() | 关闭连接 |
下面用一段简单Python程序具体实现下:
服务器端tcpserver.py
#!/usr/bin/python
import socket
HOST='172.18.2.232'
PORT=9527
BUFFER=4096
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.bind((HOST,PORT))
sock.listen(3)
print('tcpServer listen at: %s:%s\n\r' %(HOST,PORT))
while True:
client_sock,client_addr=sock.accept()
print('%s:%s connect' %client_addr)
while True:
recv=client_sock.recv(BUFFER)
if not recv:
client_sock.close()
break
print('[Client %s:%s said]:%s' %(client_addr[0],client_addr[1],recv))
client_sock.send('tcpServer has received your message')
sock.close()
客户端tcpclient.py
#!/usr/bin/python
import socket
HOST='172.18.2.232'
PORT=9527
BUFFER=4096
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((HOST,PORT))
sock.send('hello, tcpServer!')
recv=sock.recv(BUFFER)
print('[tcpServer said]: %s' % recv)
sock.close()
执行tcpserver.py
[root@centos7 ~]#python tcpserver.py
tcpServer listen at: 172.18.2.232:9527
172.18.2.232:46004 connect
[Client 172.18.2.232:46004 said]:hello, tcpServer!
执行tcpclient.py
[fei@centos7 ~]$python tcpclient.py
[tcpServer said]: tcpServer has received your message