socket
来源:互联网 发布:开关电源仿真软件psim 编辑:程序博客网 时间:2024/06/03 22:47
Socket
网络上两个程序通过socket接口进行通信,一个是服务器端,一个是客户端
socket则是对TCP/IP协议的封装和应用(程序员层面上)。
Socket本身并不是协议,而是一个调用接口(API)。
通过Socket,我们才能使用TCP/IP协议。
Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,
TCP/IP也要提供可供程序员做网络开发所用的接口,这就是Socket编程接口
创建一个socket服务端:
客户端编程
- 创建 Socket
- 连接到远程服务器
- 发送数据
- 接收回应
创建socket
#Socket client example in pythonimport socket #for sockets#create an AF_INET, STREAM socket (TCP)#返回 Socket 的描述符可用于其他 Socket 相关的函数#地址簇 : AF_INET (IPv4)#类型: SOCK_STREAM (使用 TCP 传输控制协议)s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)print 'Socket Created'
错误处理
#handling errors in python socket programsimport socket #for socketsimport sys #for exittry: #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'
注意
与 SOCK_STREAM 相对应的其他类型是 SOCK_DGRAM 用于 UDP 通讯协议,UDP 通讯是非连接 Socket,在这篇文章中我们只讨论 `SOCK_STREAM ,或者叫 TCP 。
2. 连接到服务器
连接到服务器需要服务器地址和端口号
首先获取远程主机的 IP 地址
import socket #for socketsimport sys #for exittry: #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'host = 'www.baidu.com'try: remote_ip = socket.gethostbyname( host )#获取远程主机的ip地址except socket.gaierror: #could not resolve print 'Hostname could not be resolved. Exiting' sys.exit()print 'Ip address of ' + host + ' is ' + remote_ip
gethostbyname()–>用域名或主机名获取IP地址
已经有 IP 地址了,接下来需要 指定要连接的端口
创建了一个 Socket 并进行连接
import socket #for socketsimport sys #for exittry: #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'host = 'www.baidu.com'port = 80try: 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 to remote server#连接远程服务器s.connect((remote_ip , port))print 'Socket Connected to ' + host + ' on ip ' + remote_ip
已经连接上了,接下来就是往服务器上 发送数据
。
使用 SOCK_STREAM/TCP 套接字才有“连接”的概念
UDP、ICMP 和 ARP 没有“连接”的概念
发送数据
import socket #for socketsimport sys #for exittry: #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'host = 'www.oschina.net'port = 80try: 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 to remote servers.connect((remote_ip , port))print 'Socket Connected to ' + host + ' on ip ' + remote_ipimport socket #for socketsimport sys #for exittry: #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'host = 'www.oschina.net'port = 80try: 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 to remote servers.connect((remote_ip , port))print 'Socket Connected to ' + host + ' on ip ' + remote_ip#send sone data to remote servermessage = "GET / HTTP/1.1\r\n\r\n"try: #set the whole string #向远程服务器发送字符串数据 "GET / HTTP/1.1\r\n\r\n" ,这是一个 HTTP 协议的命令,用来获取网站首页的内容。 s.sendall(message)except socket.error: #send failed print 'send failed' sys.exit()print 'Message send successfully'
接下来需要读取服务器返回的数据。
接收数据
recv 函数用于从
socket 接收数据
#Socket client example in pythonimport socket #for socketsimport sys #for exit#create an INET, STREAMing sockettry: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)except socket.error: print 'Failed to create socket' sys.exit()print 'Socket Created'host = 'oschina.net';port = 80;try: remote_ip = socket.gethostbyname( host )except socket.gaierror: #could not resolve print 'Hostname could not be resolved. Exiting' sys.exit()#Connect to remote servers.connect((remote_ip , port))print 'Socket Connected to ' + host + ' on ip ' + remote_ip#Send some data to remote servermessage = "GET / HTTP/1.1\r\nHost: oschina.net\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'#now receive data#从socket中接收服务器返回的数据reply = s.recv(4096)print reply
运行结果:
回应了我们所请求的 URL 的内容,很简单。数据接收完了,可以关闭 Socket 了
关闭 socket
s.close()
服务器端编程
- 打开 socket
- 绑定到一个地址和端口
- 侦听进来的连接
- 接受连接
- 读写数据
打开Socket
import socketimport systry: #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
bind()将 Socket 绑定到一个特定的地址和端口(自己写的服务器)
需要一个类似 connect 函数所需的 sockaddr_in 结构体。
import socketimport sysHOST = '' # Symbolic name meaning all available interfacesPORT = 8888 # Arbitrary non-privileged ports = socket.socket(socket.AF_INET, socket.SOCK_STREAM)print 'Socket created'try: s.bind((HOST, PORT))except socket.error , msg: print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] sys.exit()print 'Socket bind complete'
绑定完成后,就需要让 Socket 开始侦听连接。
很显然,你不能将两个不同的 Socket 绑定到同一个端口之上。
连接侦听
需要将 Socket 变成侦听模式
socket 的 listen 函数用于实现侦听模式:
参数:backlog,用来控制程序忙时可保持等待状态的连接数
s.listen(10)print 'Socket now listening'
接受连接
s.accept()
–>
接受TCP连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
s.accept()–>接收客户端的请求
import socketimport sysHOST = '' # Symbolic name meaning all available interfacesPORT = 8888 # Arbitrary non-privileged ports = socket.socket(socket.AF_INET, socket.SOCK_STREAM)print 'Socket created'try: s.bind((HOST, PORT))except socket.error , msg: print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] sys.exit()print 'Socket bind complete's.listen(10)print 'Socket now listening'#wait to accept a connectiong - blocking call#等待接收连接#conn是新的套接字对象,可以用来接收和发送数据。#address是连接客户端的地址。conn,addr = s.accept()#display client information#展示客户端信息print 'connected with' + addr[0] + ':' + str(addr[1])
让我们来给客户端做出点回应
sendall 函数可通过 Socket 给客户端发送数据
一直在运行的服务器
import socketimport sys#自己给定的主机和端口HOST = '' # Symbolic name meaning all available interfacesPORT = 8888 # Arbitrary non-privileged ports = socket.socket(socket.AF_INET, socket.SOCK_STREAM)print 'Socket created'try: #接收的是一个元组 s.bind((HOST, PORT))except socket.error , msg: print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] sys.exit()print 'Socket bind complete'#监听从客户端来的请求s.listen(10)print 'Socket now listening'while 1: #wait to accept a connection - blocking call conn, addr = s.accept()#建立连接,并返回1 新的套接字2.客户端地址 print 'Connected with ' + addr[0] + ':' + str(addr[1]) #对请求进行处理 # now keep talking with the client #把接收的数据实例化 data = conn.recv(1024)#用新的套接字接收数据,并实例化 #结果发给对端(即客户端) conn.sendall(data)#sendall 函数可通过 Socket 给客户端发送数据conn.close()s.close()
运行结果:
可看到客户端已经成功连接到服务器
处理多个连接请求
import socketimport sysfrom thread import *HOST = '' # Symbolic name meaning all available interfacesPORT = 8888 # Arbitrary non-privileged ports = socket.socket(socket.AF_INET, socket.SOCK_STREAM)print 'Socket created'#Bind socket to local host and porttry: s.bind((HOST, PORT))except socket.error , msg: print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1] sys.exit()print 'Socket bind complete'#Start listening on sockets.listen(10)print 'Socket now listening'#function for handling connections,this will be used to create threadsdef clientthread(conn): #send message to connected client ##send only takes string #发送到客户端 conn.send("welcome to the server.type something and hit enter\n") #infinite loop so that function do not terminate and thread do not end while True: #receiving from client #循环从客户端接收数据 data = conn.recv(1024) reply = 'OK...' +data if not data: break #向客户端发送“OK...”,客户端中显示OK表明发送成功 conn.sendall(reply) #came out of loop conn.close()while 1: #wait to accept a connection - blocking call conn,addr = s.accept() print 'Connected with' + addr[0] + ':' + str(addr[1]) #start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function. start_new_thread(clientthread ,(conn,))#进入clientthread执行s.close()
start_new_thread
( function , args [ , kwargs ] )
创建一个新的线程,返回一个线程标识符。
function是线程函数,
args是线程函数的参数,是一个list。
kwargs可选参数,可不填。
线程接管了连接并返回相应数据给客户端。
这便是我们所要介绍的服务器端编程。
================================================================================
socket编程思路
TCP服务端:
1. 创建套接字,绑定套接字到本地IP与端口 # socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.bind()
2. 开始监听连接 #s.listen()
3. 进入循环,不断接受客户端的连接请求 #s.accept()
4. 然后接收传来的数据,并发送给对方数据 #s.recv() , s.sendall()
5. 传输完毕后,关闭套接字 #s.close()
Socket编程之服务端代码:
import socket #socket模块import commands #执行系统命令模块HOST='10.0.0.245'PORT=50007s= socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义socket类型,网络通信,TCPs.bind((HOST,PORT)) #套接字绑定的IP与端口s.listen(1) #开始TCP监听while 1: conn,addr=s.accept() #接受TCP连接,并返回新的套接字与IP地址 print'Connected by',addr #输出客户端的IP地址 while 1: data=conn.recv(1024) #把接收的数据实例化 cmd_status,cmd_result=commands.getstatusoutput(data) #commands.getstatusoutput执行系统命令(即shell命令),返回两个结果,第一个是状态,成功则为0,第二个是执行成功或失败的输出信息 if len(cmd_result.strip()) ==0: #如果输出结果长度为0,则告诉客户端完成。此用法针对于创建文件或目录,创建成功不会有输出信息 conn.sendall('Done.') else: conn.sendall(cmd_result) #否则就把结果发给对端(即客户端)conn.close() #关闭连接
Socket编程之客户端代码:
import socketHOST='10.0.0.245'PORT=50007s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义socket类型,网络通信,TCPs.connect((HOST,PORT)) #要连接的IP与端口while 1: cmd=raw_input("Please input cmd:") #与人交互,输入命令 s.sendall(cmd) #把命令发送给对端 data=s.recv(1024) #把接收的数据定义为变量 print data #输出变量s.close() #关闭连接
参考:
https://www.oschina.net/question/12_76126
http://yangrong.blog.51cto.com/6945369/1339593
- socket
- socket
- Socket
- Socket
- Socket
- Socket
- Socket
- Socket
- socket
- Socket
- Socket
- Socket
- Socket
- socket
- socket
- socket
- socket
- socket
- Gson使用
- Kaldi 现在提供 TensorFlow 集成
- 表空间,序列
- 平衡二叉查找树(AVL树)总结
- JAVA springmvc自动转换日期类型的格式
- socket
- 人工智能发展现状
- jn-社团申请必须要上传图片
- 传智播客大数据全套视频教程(90G)
- [DevExpress]DateEdit设置显示日期和时间
- HDU6214 Smallest Minimum Cut【网络流】
- Session和Cookie的联系和区别
- TensorFlow Wide And Deep 模型详解与应用
- 堆和栈的区别