第一次接触到这个问题是由于tornado。在tornado.netutil中发现将socket包装成ssl socket的函数,原来可以这样写。恩, 学识浅薄。
Socket
socket对TCP/IP协议的封装和应用, 是程序员层面的。关于协议, 推荐豆瓣阅读上的《协议森林》,很不错, 适合了解一下。
python socket:
__init__(self, family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
family是协议域, 又称协议族。 协议族决定socket的地址类型,在通信中必须采用对应地址
常用的有:
AF_INET 决定要用ipv4的地址32位, 与端口号(16位的组合)
AF_INET6
AF_LOCAL 或称AF_UNIX UNIX域socket AF_UNIX决定要用一个绝对路径作为地址
AF_ROUTE
type是socket的类型
常用的有:
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW
SOCK_PACKET
SOCK_SEQPACKET
proto指定协议
IPPROTO_TCP tcp协议
IPPROTO_UDP udp协议
IPPROTO_SCTP sctp协议
IPPROTO_TIPC tipc协议
个人认为, socket就是对传输协议的封装, 使用sockt可以不用关注tcp等协议数据的处理,更接近程序员。
socket还可以结合epoll使用, 参考http://blog.csdn.net/songfreeman/article/details/51179213:
#!/usr/bin/env python import select import socket response = b'' serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.bind(('0.0.0.0', 8080)) serversocket.listen(1) # 因为socket默认是阻塞的,所以需要使用非阻塞(异步)模式。 serversocket.setblocking(0) # 创建一个epoll对象 epoll = select.epoll() # 在服务端socket上面注册对读event的关注。一个读event随时会触发服务端socket去接收一个socket连接 epoll.register(serversocket.fileno(), select.EPOLLIN) try: # 字典connections映射文件描述符(整数)到其相应的网络连接对象 connections = {} requests = {} responses = {} while True: # 查询epoll对象,看是否有任何关注的event被触发。参数“1”表示,我们会等待1秒来看是否有event发生。 # 如果有任何我们感兴趣的event发生在这次查询之前,这个查询就会带着这些event的列表立即返回 events = epoll.poll(1) # event作为一个序列(fileno,event code)的元组返回。fileno是文件描述符的代名词,始终是一个整数。 for fileno, event in events: # 如果是服务端产生event,表示有一个新的连接进来 if fileno == serversocket.fileno(): connection, address = serversocket.accept() print('client connected:', address) # 设置新的socket为非阻塞模式 connection.setblocking(0) # 为新的socket注册对读(EPOLLIN)event的关注 epoll.register(connection.fileno(), select.EPOLLIN) connections[connection.fileno()] = connection # 初始化接收的数据 requests[connection.fileno()] = b'' # 如果发生一个读event,就读取从客户端发送过来的新数据 elif event & select.EPOLLIN: print("------recvdata---------") # 接收客户端发送过来的数据 requests[fileno] += connections[fileno].recv(1024) # 如果客户端退出,关闭客户端连接,取消所有的读和写监听 if not requests[fileno]: connections[fileno].close() # 删除connections字典中的监听对象 del connections[fileno] # 删除接收数据字典对应的句柄对象 del requests[connections[fileno]] print(connections, requests) epoll.modify(fileno, 0) else: # 一旦完成请求已收到,就注销对读event的关注,注册对写(EPOLLOUT)event的关注。写event发生的时候,会回复数据给客户端 epoll.modify(fileno, select.EPOLLOUT) # 打印完整的请求,证明虽然与客户端的通信是交错进行的,但数据可以作为一个整体来组装和处理 print('-' * 40 + '\n' + requests[fileno].decode()) # 如果一个写event在一个客户端socket上面发生,它会接受新的数据以便发送到客户端 elif event & select.EPOLLOUT: print("-------send data---------") # 每次发送一部分响应数据,直到完整的响应数据都已经发送给操作系统等待传输给客户端 byteswritten = connections[fileno].send(requests[fileno]) requests[fileno] = requests[fileno][byteswritten:] if len(requests[fileno]) == 0: # 一旦完整的响应数据发送完成,就不再关注写event epoll.modify(fileno, select.EPOLLIN) # HUP(挂起)event表明客户端socket已经断开(即关闭),所以服务端也需要关闭。 # 没有必要注册对HUP event的关注。在socket上面,它们总是会被epoll对象注册 elif event & select.EPOLLHUP: print("end hup------") # 注销对此socket连接的关注 epoll.unregister(fileno) # 关闭socket连接 connections[fileno].close() del connections[fileno] finally: # 打开的socket连接不需要关闭,因为Python会在程序结束的时候关闭。这里显式关闭是一个好的代码习惯 epoll.unregister(serversocket.fileno()) epoll.close() serversocket.close()
SSL
ssl个人喜欢把它理解为一种加密协议。采用对称算法进行加密。SSL协议的版本只有1和2只提供服务器认证, 版本3添加了客户端认证,此认证同时需要客户端和服务器的数字证书。
盗图:参考https://www.wosign.com/Basic/howsslwork.htm
tornado中将socket包装成ssl的代码:
#定义SSL的一些参数 _SSL_CONTEXT_KEYWORDS = frozenset(['ssl_version', 'certfile', 'keyfile', 'cert_reqs', 'ca_certs', 'ciphers']) def ssl_options_to_context(ssl_options): """尝试将ssl的option参数转化为ssl.SSLContext对象""" if isinstance(ssl_options, dict): # 要求ssl option的参数必须是_SSL_CONTEXT_KEYWORDS预定义的 assert all(k in _SSL_CONTEXT_KEYWORDS for k in ssl_options), ssl_options if (not hasattr(ssl, 'SSLContext') or isinstance(ssl_options, ssl.SSLContext)): return ssl_options context = ssl.SSLContext( ssl_options.get('ssl_version', ssl.PROTOCOL_SSLv23)) if 'certfile' in ssl_options: context.load_cert_chain(ssl_options['certfile'], ssl_options.get('keyfile', None)) if 'cert_reqs' in ssl_options: context.verify_mode = ssl_options['cert_reqs'] if 'ca_certs' in ssl_options: context.load_verify_locations(ssl_options['ca_certs']) if 'ciphers' in ssl_options: context.set_ciphers(ssl_options['ciphers']) if hasattr(ssl, 'OP_NO_COMPRESSION'): context.options |= ssl.OP_NO_COMPRESSION return context def ssl_wrap_socket(socket, ssl_options, server_hostname=None, **kwargs): #包装函数 context = ssl_options_to_context(ssl_options) if hasattr(ssl, 'SSLContext') and isinstance(context, ssl.SSLContext): if server_hostname is not None and getattr(ssl, 'HAS_SNI'): return context.wrap_socket(socket, server_hostname=server_hostname, **kwargs) else: return context.wrap_socket(socket, **kwargs) else: return ssl.wrap_socket(socket, **dict(context, **kwargs))
相关推荐
《易语言SSL_Socket通信模块源码解析与应用》 在信息技术日新月异的今天,网络通信的安全性越来越受到重视。SSL(Secure Sockets Layer)协议作为网络安全传输的重要手段,广泛应用于各种网络服务中。易语言,作为...
5. 通过SSLContext获取SSLServerSocketFactory或SSLSocketFactory来创建SSLServerSocket或SSLSocket,进行安全的通信。 由于SSL/TLS协议的复杂性,开发人员在使用JSSE进行SSL/TLS编程时需要深入理解相关的加密原理...
在Java编程语言中,SSLSocket(Secure Sockets Layer Socket)是用于实现安全网络通信的重要组件,它基于SSL/TLS协议栈,为应用程序提供加密的数据传输服务。本教程将深入探讨Java中的SSLSocket应用,包括其基本概念...
6. **连接SSL**:将SSL结构体与Socket绑定,使用`SSL_set_fd()`函数设置Socket描述符。然后,调用`SSL_connect()`来建立SSL连接,这会进行SSL握手,包括证书交换、密钥协商等。 7. **发送和接收数据**:SSL连接建立...
与普通`Socket`类似,`SSLSocket`提供了`getInputStream()`和`getOutputStream()`方法,用于读取和写入加密的数据。需要注意的是,由于SSL握手的存在,必须等待握手完成才能进行读写操作,否则可能会抛出异常。 6....
4. **建立连接**:使用SSLSocketFactory创建SSLSocket实例,并通过其建立与服务器的连接。注意,SSLSocket在建立连接时会进行SSL握手,验证对方的身份。 5. **数据传输**:连接建立后,就可以通过SSLSocket的输入...
SSLSocket socket = (SSLSocket) sf.createSocket("server_address", server_port); ``` 然后,我们可以通过SSLSocket进行正常的Socket通信,包括输入流和输出流的读写。在开始通信之前,会进行SSL握手,这是一个...
「C#实现SSLSocket加密通讯方法详解」 在网络通讯中,安全性是一个非常重要的方面,而SSL/TLS协议则是最常用的加密通讯协议之一。C#作为一个强大的编程语言,可以轻松地实现SSL/TLS协议的加密通讯。下面将详细介绍...
Java SSL(Secure Socket Layer)套接字是一种用于在两个应用程序之间建立安全通信通道的协议,主要目的是为了确保数据传输的安全性。SSL通过使用加密技术来保护数据,防止未经授权的访问和篡改。在Java中,我们可以...
详细介绍了java如何使用SSL来进行socket通信了 最主要的是介绍了如何使用keytool来生成.keystore文件 ps:设置一分是希望那些刚入门或则对csdn访问不多的朋友 多花点时间 表面上市搞积分 事实上是有帮助的。 如果你...
5. **将SOCKET与SSL上下文关联**:使用`SSL_CTX_new()`创建的SSL上下文,通过`SSL_new()`创建一个SSL对象,并用`SSL_set_fd()`将SOCKET描述符绑定到SSL对象。 6. **SSL握手**:执行SSL/TLS的握手过程,这包括证书...
在本篇博文中,我们将深入探讨如何利用Apache MINA库实现基于TLS/SSL的NIO(非阻塞I/O)Socket通信。MINA是一个高度可扩展的网络应用框架,广泛用于构建高性能、高并发的网络应用程序,如服务器端的TCP和UDP服务。...
SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket(); sslSocket.setHostnameVerifier(hostnameVerifier); ``` 通过这样的配置,开发者可以确保在Android 7.0上,即使面对非标准的证书配置,也能正常...
- 设置Socket连接:`SSL_set_fd()`将Socket描述符与SSL对象关联。 - 进行SSL握手:调用`SSL_connect()`或`SSL_accept()`进行客户端或服务器端的握手过程。 - 数据传输:使用`SSL_read()`和`SSL_write()`进行加密...
4. 创建Socket连接:与服务器建立普通Socket连接。 5. 创建SSL连接对象:使用`SSL_new()`,关联到Socket。 6. SSL握手:调用`SSL_connect()`进行握手。 7. 数据传输:使用`SSL_read()`和`SSL_write()`进行加密通信。...
在Android中,通常使用java.net.SSLSocket和SSLSocketFactory类来实现SSL/TLS的Socket通信。 3. **生成BKS文件**: BKS(Bouncy Castle Keystore)是Android上常用的SSL证书存储格式。为了实现SSL加密,需要一个...
ssl套接字通信服务端和客户段 ssl单向认证、双向认证
* MOD-NAME : sslsocket.h * LONG-NAME : * * AUTHOR : Martin Ziacek (martin.ziacek@pobox.sk) * DEPARTMENT : * TELEPHONE : * CREATION-DATE : 29/05/2001 15:27:01 * SP-NO : * FUNCTION : * ***********...
**SSLDemo安全Socket通信Demo**是一个用于演示如何在C#编程环境中实现基于Socket的安全通信的应用程序。这个Demo深入展示了网络安全的重要概念,如数字签名、SSL(Secure Socket Layer)协议、非对称加密和对称加密...