一.Scocket基本原理
1.Socket的概念
Socket的中文翻译是套接字,它是TCP/IP网络环境下应用程序与底层通信驱动程序之间运行的开发接口,它可以将应用程序与具体的TCP/IP隔离开来,使得应用程序不需要了解TCP/IP的具体细节,就能够实现数据传输。在网络应用程序中,Socket通信是基于客户端/服务器结构。客户端是发送数据的一方。服务器时刻准备接受来自客户端的数据,对做出响应。
2.具体实现
1.创建socket:
首先要创建 socket,用 Python 中 socket 模块的函数 socket 就可以完成:
#-*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print 'socket Created'
函数 socket.socket 创建一个 socket,返回该 socket 的描述符,将在后面相关函数中使用。该函数带有两个参数如下:
Address Family:可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信)
Type:套接字类型,可以是 SOCKET_STREAM(流式套接字,主要用于 TCP 协议)或者SOCKET_DGRAM(数据报套接字,主要用于 UDP 协议)。
2.连接服务器:
socket 使用 (IP地址,协议,端口号) 来标识一个进程,那么我们要想和服务器进行通信,就需要知道它的 IP地址以及端口号。Python 提供了一个简单的函数 socket.gethostbyname 来获得远程主机的 IP 地址:
#获取服务器IP地址
host = 'www.baidu.com'
port = 80
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
#could not resolve
print 'Hostname could not be resolved. Exiting'
sys.exit()
print 'Ip address of ' + host + ' is ' + remote_ip
使用连接函数 connect 连接到该 IP 的某个特定的端口上了,下面例子连接到 80 端口上(是 HTTP 服务的默认端口):
#连接服务器
s.connect((remote_ip , port))
print 'Socket Connected to ' + host + ' on ip ' + remote_ip
3.发送数据:
例如发送字符串GET / HTTP/1.1\r\n\r\n,这是一个 HTTP 请求网页内容的命令。
#发送数据
message = "GET / HTTP/1.1\r\n\r\n"
try :
#Set the whole string
s.sendall(message)
except socket.error:
#Send failed
print 'Send failed'
sys.exit()
print 'Message send successfully'
4.接收数据:
#接受服务器反馈的数据
reply = s.recv(4096)
print reply
5.关闭socket:
#关闭套接字
s.close()
二.TCPServer简单实现流程
import socket
import time
HOST = ''
PORT = 12456
ADDR = (HOST, PORT)
bufferSize = 1024
tcpServerSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpServerSock.bind(ADDR)
tcpServerSock.listen(5)
while True:
print 'waiting for connection...'
tcpClientSock, addr = tcpServerSock.accept()
print 'connected from:', addr
while True:
data = tcpClientSock.recv(bufferSize)
if not data:
break
data = str.upper(data)
tcpClientSock.send('[%s] %s' % (time.ctime(), data))
tcpClientSock.close()
tcpServerSock.close()
三.TCP群聊服务端实现
1.服务端
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:server.py
import socket # 导入 socket 模块
s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 12345 # 设置端口
s.bind((host, port)) # 绑定端口
s.listen(5) # 等待客户端连接
while True:
c, addr = s.accept() # 建立客户端连接。
print '连接地址:', addr
c.send('欢迎访问菜鸟教程!')
c.close() # 关闭连接
2.客户端
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 文件名:client.py
import socket # 导入 socket 模块
s = socket.socket() # 创建 socket 对象
host = socket.gethostname() # 获取本地主机名
port = 12345 # 设置端口号
s.connect((host, port))
print s.recv(1024)
s.close() # 关闭连接
现在我们打开两个终端,第一个终端执行 server.py 文件:
$ python server.py
第二个终端执行 client.py 文件:
$ python client.py
欢迎访问菜鸟教程!
这时我们再打开第一个终端,就会看到有以下信息输出:
连接地址: ('192.168.0.118', 62461)