参考资料:socket学习教程
1.什么是Socket
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个Socket。Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。
一个关于Socket的经典解释:
Socket非常类似于电话插座。以一个国家级电话网为例,电话的通话双方相当于相互通信的2个进程,区号是它的网络地址;区内一个单位的交换机相当于一台主机,主机分配给每个用户的局内号码相当于Socket号。任何用户在通话之前,首先要占有一部电话机,相当于申请一个Socket;同时要知道对方的号码,相当于对方有一个固定的Socket。然后向对方拨号呼叫,相当于发出连接请求(假如对方不在同一区内,还要拨对方区号,相当于给出网络地址)。假如对方在场并空闲(相当于通信的另一主机开机且可以接受连接请求),拿起电话话筒,双方就可以正式通话,相当于连接成功。双方通话的过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向Socket发送数据和从socket接收数据。通话结束后,一方挂起电话机相当于关闭Socket,撤消连接。
2.Scoket怎样连接
根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。
(1)服务器监听:是服务器端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。
(2)客户端请求:是指由客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
(3)连接确认:是指当服务器端套接字监听到或者说接收到客户端套接字的连接请求,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。
实际操作:
创建Socket
顺带学习了下try函数的用法~~
import socket #for sockets
import sys #for exit
try:
#create an AF_INET, STREAM socket (TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
sys.exit();
print ('Socket Created')
注意:这个脚本在编写过程中绝对不能以socket.py的形式命名,否则在运行过程中CMD报错!
AF_INET:IPV4型地址簇,决定了socket的地址类型,在通信中必须采用对应的地址
STREAM socket (TCP):指定了Socket类型。她使用 TCP传输控制协议。
连接到服务器
host = 'www.oschina.net'
port = 80
try:
remote_ip = socket.gethostbyname( host ) #用来获取网站Ip
except socket.gaierror:
print 'Hostname could not be resolved.Exiting'
sys.exit()
print "Ip address of" + host +" is: " + remote_ip
#连接到网络
s.connect((remote_ip , port))
print "Socket Connected to " + host + 'on ip ' + remote_ip
这段程序创建了一个 Socket 并进行连接。这个逻辑相当于构建了一个端口扫描器。
接收数据,完成后关闭
#send some data to remote server
message = "GET/ HTTP/1.1\r\nHost: oschina.net\r\n\r" #请求获取主页信息
try :
s.sendall(message) # 发送数据
except socket.error:
print "Send failed"
sys.exit() #send failed
print "Message send successfully"
#now receive data
reply = s.recv(4096)
print reply
s.close()