python socket编程---从使用Python开发一个Socket示例说到开发者的思维和习惯问题
今天主要说的是一个开发者的思维和习惯问题。
思维包括编程的思维和解决一个具体问题的分析思维,分析思路,分析方法,甚至是分析工具。
无论是好习惯还是不好的习惯,都是在者一天一天的思维中形成的。那些不好的习惯,久了确实不好改。所以说,如果今天你认识到了,那么就从今天开始改,早改早受益,晚改痛苦一生。
先说一下今天的引子,那就是使用Python开发一个简单的Socket应用,就是一个client/server通信的小例子。
假设现在需要我们使用python开发一个socket的聊天应用,可能会遇到下面的问题。
- python没有用过,怎么办呢?
- 我用过python,可是我们开发过socket方面的应用?
- 我还不知道socket是什么东西呢?
- socket大概我记得,套接字吗,ip+port,具体的tcp和udp我不不太清楚。
其实我们几乎每天都可能会解决一些我们没有解决过的问题,有可能是没有用过的类库,没有听过的技术,没有用过的语言,甚至是没有听过的概念。
其实,这些都不是问题。只要你有一个较好的思维习惯,较好的思维方式,较好的解决问题的方法,那你就什么都不用怕了。
大家可以仔细的看看和研究一下,其实这10年20年,没有出现任何新的技术,出现的都是新的概念,所谓的新技术都是对老技术的挖掘,重新组合,应用到新的领域,用新的视角解决新的问题,其实用到的根本还是那些技术的技术知识。
这些技术知识包括:
- 语言的语法,语言的基本结构(顺序,选择,循环)。
- 技术的基础理论,例如,数据库理论,文件系统理论,今天我们演示用的socket通信理论。
当然了,除了上面的硬技术,你还需要一些软技术。例如,思考方法,好的习惯,好的工具,好的沟通,好的理解力,好的领悟力。
现在出现的东西都是上面这些东西的组合,或者将这些组合解决了新出现的问题,又或者是变了一种思路来解决老问题,等等诸如此类的组合。
举个例子来说吧。“云计算”,很火吧,各种语言的云计算,各种框架的云计算,但是如果你陷入这些语言和框架,结果可想而知,精力被耗尽,但是不见得真正理解多少,甚至是框架都会不完,因为太多了。
这就需要我们加强理论基础知识,云的理论基础就是分布式,分布式出来很多年了吧。好了,先学习和理解分布式,理解云就迎刃而解了。分布式+调度+服务器集群+通信=云,你看看,哪个是新的,哪个是以前没有的,对不对呢!
就拿socket举例子吧。只举个小例子,就是分别用tcp和udp实现聊天。
我们先不要google找python socket代码。我们先回忆一下我们学过的socket通信部分,或者说先找一本socket通信的书或者文章,看看通信的原理和过程。当然,不是要你通篇看完,通篇理解,完全弄懂。tcp和udp里面的细节你可能不知道,没有关系,如果需要的话,后面再来看。但至少你可以使用伪代码描述tcp和udp的通信流程,或者在纸上可以画出通信流程,使用流程图描述你要实现的功能。
别小看伪代码和流程图这两个简单的东西,它代表了你的思考过程,你的思维方法,和你选择的思维工具,是良好习惯的开端,一定要坚持,直到这些都成为你的习惯。
有了这些东西,别人会对你高看一眼的,会觉得你比较靠谱,就会给你更有挑战的工作,给你表现的机会,那么你就。。。。。。。。。。。。。。大家都明白的。你的各种想法都有机会实现了,否则就都是空白。
图1 tcp通信图
上图是一张socket的tcp通信简图,我们都知道tcp的通信需要三次握手。tcp是可靠的、面向连接的、尽力传输的协议,而udp是不可靠的、面向非连接的、不尽力传输的协议。但是不可靠不代表它没有用,udp有自己的应用场景,语音和视频几乎都在使用udp协议,它的不可靠只是相对于tcp来说的,但是它的好处就是效率,高效在某些场景要比可靠性重要。这就涉及trade-off了,也就是权衡,需要根据你的应用权衡利弊,然后进行选择。
在socket选择初始化一个tcp协议的socket之后,就会绑定一个地址和端口,然后开始listen,客户端连接这个listen的tcp之后,服务端会accept这个请求,然后产生一个新的socket,双方使用这个新的socket(地址和端口,地址还是上面listen的地址,端口会是一个新的,这个从打印出的结果中可以看出)进行后续的通信。原来的端口会继续的listen新的请求。
下面是tcpServer的代码
- import socket
- HOST='192.168.0.37'
- PORT=50000
- BUFFER=4096
- sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- sock.bind((HOST,PORT))
- sock.listen(0)
- 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()
socket.SOCK_STREAM是用来指定socket是基于tcp协议的。
下面是对应的客户端代码
- import socket
- HOST='192.168.0.37'
- PORT=50000
- 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()
下面是udpServer的代码
- import socket
- HOST='192.168.0.37'
- PORT=50001
- BUFFER=4096
- sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
- sock.bind((HOST,PORT))
- #sock.listen(0)
- 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_addr=sock.recvfrom(BUFFER)
- if not recv:
- break
- print('[Client %s:%s said]:%s' % (client_addr[0],client_addr[1],recv))
- sock.sendto('tcpServer has received your message',client_addr)
- sock.close()
你会发现由于udp是非连接的,不需要三次握手,所以不需要进行listen,也不需要accept,直接通信就可以了。还有就是初始化socket的时候,通过指定
- socket.SOCK_DGRAM
来实现初始化的socket是基于udp协议的。
如果初始化的是udp协议的socket,就不需要listen,也不存在accept,双方通信的同时指明对方的地址和端口就可以了。
对应的客户端代码:
- #!/usr/bin/env python
- # -*- coding: UTF-8 -*-
- import socket
- HOST='192.168.0.37'
- PORT=50001
- BUFFER=4096
- sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
- sock.connect((HOST,PORT))
- sock.send('hello, tcpServer!')
- recv=sock.recv(BUFFER)
- print('[tcpServer said]: %s' % recv)
- sock.close()
说了上面这么多,我的主要意思就是。开发者要加强理论基础的学习,不要穷追猛打那些语言和框架,至少在穷追猛打的过程中,分出更多的精力关注基础知识,基础牢靠,上层建筑才稳固且长久。
对于少数人,这已经形成他们的习惯了,他们已经及早的认识到了这个问题,这么多年都是这么做的。
对于大多数开发者来说,都是遇到问题,找语法,找例子,拔过来,改一改,debug,看效果,再debug,再看效果。问题可能解决了,但是过程是痛苦至极,年前的时候还不觉得如何,时间一长,发现开发原来是这么的没有意思,这么的枯燥,每天都是这个过程,没有新意,这么多语言框架,什么时候才能学完呢,感觉自己被拉着走,甚至是拖着走,没有解脱的一天,除非dead。
不过也没有关系,大多数人都是这么过来的,那些牛人也是这么过来的,只是他们很早就意识到了这个问题,然后及早的修正,及早的进入一条快车道。就像我一直说的,开发者的几个阶段是不能越过的,但是你可以比别人多花时间和精力,缩短这些必经阶段的时间,这个很重要的。
如果你今天认识到了,那么不要拖到明天,不要拖到下个项目,不要拖到下一个模块,从现在开始,从这个项目开始,从这个模块开始,修正自己,后面的路就会舒服很多。我不能保证后面你会如何如何,但是敢保证你会越来越舒服,就算是一直coding到退休,也不是在痛苦中coding,而是舒舒服服的coding。没有人会对我们说“你30岁了,还在coding。。。。。。”,因为我们coding的过程,我们coding出来的结果配得上我们的年龄了。
python socket编程---从使用Python开发一个Socket示例说到开发者的思维和习惯问题的更多相关文章
- C# socket编程实践——支持广播的简单socket服务器
在上篇博客简单理解socket写完之后我就希望写出一个websocket的服务器了,但是一路困难重重,还是从基础开始吧,先搞定C# socket编程基本知识,写一个支持广播的简单server/clie ...
- 探索 Python、机器学习和 NLTK 库 开发一个应用程序,使用 Python、NLTK 和机器学习对 RSS 提要进行分类
挑战:使用机器学习对 RSS 提要进行分类 最近,我接到一项任务,要求为客户创建一个 RSS 提要分类子系统.目标是读取几十个甚至几百个 RSS 提要,将它们的许多文章自动分类到几十个预定义的主题领域 ...
- Python GUI编程(Tkinter) windows界面开发
Python实现GUI简单的来说可以调用Tkinter库,这样一般的需求都可以实现,显示简单的windows窗口代码如下: python_gui.py 1 #!C:\Python27\python.e ...
- python网络编程--TCP客户端的开发
#导入socket模块 2 import socket 3 #参数说明 4 """ 5 socket类的介绍 6 创建客户端socket对象 7 socket.socke ...
- 【Python网络编程】利用Python进行TCP、UDP套接字编程
之前实现了Java版本的TCP和UDP套接字编程的例子,于是决定结合Python的学习做一个Python版本的套接字编程实验. 流程如下: 1.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接 ...
- 利用socket编程在ESP32上搭建一个TCP客户端
通过之前http://www.cnblogs.com/noticeable/p/7636582.html中对socket的编程,已经可以知道如何通过socket编程搭建服务器和客户端了,现在,就在ES ...
- 网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程
Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服 ...
- Socket编程学习之道:揭开Socket编程的面纱
对TCP/IP.UDP.Socket编程这些词你不会非常陌生吧?随着网络技术的发展.这些词充斥着我们的耳朵. 那么我想问: 1. 什么是TCP/IP.UDP? 2. S ...
- socket编程以及select、epoll、poll示例详解
socket编程socket这个词可以表示很多概念,在TCP/IP协议中“IP地址 + TCP或UDP端口号”唯一标识网络通讯中的一个进程,“IP + 端口号”就称为socket.在TCP协议中,建立 ...
随机推荐
- Win7的64位系统如何搭建安卓Android开发环境
在搭建安卓Android开发环境,那么现在比较主流的Win7的64位操作系统如何搭建呢?其实很简单,不需要设置任何环境变量,只需要下载两个程序包(ADT和JDK),下载的时候注意选择相应的64位程序包 ...
- Tcp Socket非阻塞recv
最近看了许多关于网络编程的资料,自己小记一下,以方便以后查找. 什么是阻塞socket,什么是非阻塞socket.对于这个问题,我们要先弄清什么是阻塞/非阻塞.阻塞与非阻塞是对一个文件描述符指定的文件 ...
- jquery-图片轮播(新手请大神指教一下)
这是我刚学jquery写的,感觉效果不是很好. #scrollPics{ height: 330px; width: 980px; margin-bottom: 10px; overflow: hid ...
- android抓日志
1. adb logcat -c 清楚以前的日志 adb logcat -s 过滤 adb logcat -s *:E adb logcat -v 指定输出的格式 adb logcat -v brie ...
- TCP/IP体系结构-测试人员必须理解的
如果还想在测试这条路上继续走下去的话,那么下面这些东西就是我们必须去掌握的,至少你还不想止步于简单的黑盒测试--其实,一直想去接触Linux下的应用测试,这样能学到东西会很多,而且会非常的受用.之前听 ...
- 使用CFile生成log文件的方法
下面实例是在退出程序点击退出按钮时,在主程序的根目录下生成一个Log记录,用来记录程序的退出时间,具体实现代码与调试代码如下: void CDebugDlg::OnClose(){ // TODO: ...
- VS中的快捷键快速格式化代码,使好看,整齐
在VC2005中,快捷键是Ctrl + K, Ctrl + F, 这是一个组合键,即先按Ctrl + K, 这时候编辑器会等待下一个按键动作,此时再按Ctrl + F, 即可以格式化代码了,当然,也可 ...
- thinkphp的目录结构设计经验总结
用thinkphp开发了好些项目了:最近准备抽空写一些经验总结: 希望能给刚开始接触tp的童鞋们提供一些开发的方案:少走一些弯路:少踩一些坑: 这些绝对都是些精华干货:耐着性子阅读:相信肯定是会有收获 ...
- php mysql数据库 分页与搜索
<?php/** * Created by coder meng. * User: coder meng * Date: 2016/8/29 10:27 */header("Conte ...
- OpenCV使用边缘提取、腐蚀、轮廓进行车牌定位
http://blog.csdn.net/superdont/article/details/24935383 OpenCV使用边缘提取.腐蚀.轮廓进行车牌定位 2014-05-03 21:38 67 ...