客户端

客户端主要有4个步骤:

1)创建一个socket以连接服务器。

socket = socket.socket(family, type),family参数代表地址家族,可为AF_INET(包括Internet地址,和IPV4对应)或AF_UNIX(用于同一台机器上的进程间通信)。type,家族协议,协议家族一般表示TCP通信的SOCK_STREAM或者表示UDP通信的SOCK_DGRAM。

2)使用socket的connect方法连接服务器。

对于AF_INET家族,连接格式如下:socket.connect(host, port) ,host代表服务器主机名或IP,port代表服务器进程所绑定的端口号。

3)处理阶段,客户和服务器将通过send方法和recv方法通信。如:

    tcpCliSock.send(data)
data = tcpCliSock.recv(BUFSIZE) #从 socket 中接收数据,最多 BUFSIZE个字符

4)传输结束,客户通过调用socket的close方法关闭连接。

    tcpCliSock.close()

代码如下:

#from socket import *
import socket
HOST='localhost' #服务器ip或者名,由于我们在同一台电脑上进行测试,所以 HOST里放的是本机的主机名
PORT= 20000 #服务器端口号,端口号要与服务器上的设置完全相同(不然就没办法通讯)。
BUFSIZE = 1024
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #建立socket
s.connect((HOST,PORT)) #连接服务器socket '''
客户端也有一个无限循环,
客户端的循环在以下两个条件的任意一个发生后就退出:
用户没有输入任何内容,或服务器由于某种原因退出,
导致 recv()函数失败。否则,在一般情况下,客户端会把用户输入的字符串
发给服务器进行处理,然后接收并显示服务器传回来的,加了时间戳的字符串。
''' while True: #通过send和recv与服务器进行通信
data=raw_input('Enter a string that you want to send:')
if not data:
break
s.send(data)
data=s.recv(BUFSIZE)
if not data:
break
print data
s.close() #关闭socket

服务器端

服务器端主要是有6个步骤:

1)创建一个socket对象,方式如客户端。

2)将socket绑定到指定地址。这是通过socket对象的bind方法来实现的:socket.bind(address) 。由AF_INET所创建的套接字,address地址必须是一个双元素元组,格式是(host,port)。如果所绑定的地址或者端口正在使用,那么将会出错。

3)使用socket套接字的listen方法接收连接请求。socket.listen(backlog)   backlog指定最多允许多少个客户连接到服务器。listen()函数的参数只是表示最多允许多少个连接同时连进来,后来的连接就会被拒绝掉。

4)第四步是服务器套接字通过socket的accept方法等待客户请求一个连接。connection, address = socket.accept()  。调用accept方法时,socket会进入“waiting”状态。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。

5)处理阶段,服务器和客户端通过send和recv方法进行数据的传输。服务器调用send,并采用字符串形式向客户发送信息。send方法返回已发送的字符个数。服务器使用recv方法从客户接收信息。

调用recv时,服务器必须指定一个整数,它对应于可通过本次方法调用来接收的最大数据量。recv方法在接收数据时会进入“blocked”状态,最后返回一个字符串,用它表示收到的数据。(怎么理解?)

6)传输结束,调用socket的close方法关闭连接。

代码如下:

import socket
from time import ctime
HOST = '' #HOST 变量为空,表示 bind()函数可以绑定在所有有效的地址上。
PORT =20000 #选用了一个随机生成的未被占用的端口号。
BUFSIZE =1024 #1kb
tcpSerSock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #建立socket
tcpSerSock.bind((HOST,PORT)) #绑定客户端的socket
tcpSerSock.listen(5) #监听的客户端数目限制 while True: #这个while是对接收的客户端循环,数目为0时候停止。
print 'waiting for connection...'
tcpCliSock,CliAddr=tcpSerSock.accept() #通过socket的accept方法等待客户请求一个连接
print '...connected from :', CliAddr
while True: #开始进行数据传输
data= tcpCliSock.recv(BUFSIZE)
if not data:
break
print '[%s] %s' % (ctime(), data) #得到客户的消息后,我们在消息前加一个时间戳然后返回
tcpCliSock.send('[%s] %s' % (ctime(), data))
tcpCliSock.close()
tcpSerSock.close()

运行:

存放在指定文件夹下,打开并运行(F5),记住:一定要先运行服务器端!

客户端:

服务器端:

由上面的结果,过程是:

服务器一直处于等待时间,客户端通过ip和端口号找到服务器,通过三次握手建立连接。接下来客户端将数据发送给服务器,服务器收到后进行确认,在数据上加上时间戳,回显给客户端。,客户端也会无线循环,直到不再输入任何数据。其中服务器端永远不会关闭,一直处于等待状态,tcpSerSock.close()不会执行。

ps:执行

tcpCliSock.close()有如下几种情况:
1)输入空的字符
2)关掉客户端
当重新进行连接的时候,每次的客户端端口都是不一样的随机的。这是由系统随机分配的。

增加超时机制:clientsock.settimeout(t)

调用socket的settimeout()函数,向其传递参数,表明超时时间设置。当访问一个socket,如果经过了参数设定的时间后,什么都没有发生,则会产生一个socket.timeout异常。

 import socket,traceback
host=''
port=12345
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(1) while 1:
try:
clientsock,clientaddr=s.accept()
except KeyboardInterrupt:
raise
except:
traceback.print_exc()
continue
clientsock.settimeout(5)
try:
print "连接来自:",clientsock.getpeername()
while 1:
data=clientsock.recv(4096)
if not len(data):
break
clientsock.sendall(data)
clientsock.sendall("\nI get it!\n")
## t=raw_input('input the word:')
## clientsock.sendall(t)
except (KeyboardInterrupt,SystemExit):
raise
except socket.timeout:
print '连接超时'
pass
except:
traceback.print_exc() try:
clientsock.close()
except KeyboardInterrupt:
raise
except:
traceback.print_exc()

 半开放socket:

通过调用shutdown()使得socket半开放,它可以为了检查错误、安全防护和防止缓存溢出等原因而关闭一个方向的通信。

附录1.

以上步骤可以简化为:

http://www.cnblogs.com/xiaowuyi/archive/2012/08/06/2625509.html

附录2.

socket库中利用getservbyname()函数可以查询端口号:

import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
port=socket.getservbyname('http','tcp')
port的返回值为80。若改为:
port=socket.getservbyname('smtp','tcp')
port的返回值为25。

建立socket连接后,可以通过getsockname()获取本身的ip地址和端口号,也可以通过getpeername()显示远程机器的ip地址和端口号。

Socket 模块的类方法
类方法 说明
Socket 低层网络接口(每个 BSD API)
socket.socket(family, type) 创建并返回一个新的 socket 对象
socket.getfqdn(name) 将使用点号分隔的 IP 地址字符串转换成一个完整的域名
socket.gethostbyname(hostname) 将主机名解析为一个使用点号分隔的 IP 地址字符串
socket.fromfd(fd, family, type) 从现有的文件描述符创建一个 socket 对象

Socket 模块的实例方法
实例方法 说明
sock.bind( (adrs, port) ) 将 socket 绑定到一个地址和端口上
sock.accept() 返回一个客户机 socket(带有客户机端的地址信息)
sock.listen(backlog) 将 socket 设置成监听模式,能够监听 backlog 外来的连接请求
sock.connect( (adrs, port) ) 将 socket 连接到定义的主机和端口上
sock.recv( buflen[, flags] ) 从 socket 中接收数据,最多 buflen 个字符
sock.recvfrom( buflen[, flags] ) 从 socket 中接收数据,最多 buflen 个字符,同时返回数据来源的远程主机和端口号
sock.send( data[, flags] ) 通过 socket 发送数据
sock.sendto( data[, flags], addr ) 通过 socket 发送数据
sock.close() 关闭 socket
sock.getsockopt( lvl, optname ) 获得指定 socket 选项的值
sock.setsockopt( lvl, optname, val ) 设置指定 socket 选项的值

http://www.cnblogs.com/xiaowuyi/archive/2012/08/06/2625509.html

python 网络编程(三)---TCP 服务器端客户端实现的更多相关文章

  1. 2015/12/14 Python网络编程,TCP/IP客户端和服务器初探

    一直不是很清楚服务器的定义,对于什么是服务器/客户端架构也只有一个模糊的感觉.最近开始学习,才明白一些什么服务器和客户端的关系. 所谓的服务器,就是提供服务的东西,它是一个硬件或者软件,可以向一个或者 ...

  2. python网络编程05 /TCP阻塞机制

    python网络编程05 /TCP阻塞机制 目录 python网络编程05 /TCP阻塞机制 1.什么是拥塞控制 2.拥塞控制要考虑的因素 3.拥塞控制的方法: 1.慢开始和拥塞避免 2.快重传和快恢 ...

  3. python网络编程(TCP/IP、发邮件)

    TCP/IP 关注公众号"轻松学编程"了解更多. 计算机为了联网,就必须规定通讯协议,早期的计算机网络是由各个厂商规定的一些协议,他们之间互不兼容. 为了把全世界的电脑能够连接到一 ...

  4. python网络编程三次握手和四次挥手

    TCP是因特网中的传输层协议,使用三次握手协议建立连接.当主动方发出SYN连接请求后,等待对方回答SYN+ACK[1],并最终对对方的 SYN 执行 ACK 确认.这种建立连接的方法可以防止产生错误的 ...

  5. python网络编程:TCP通讯模板、粘包及解决方案、自定义报头

    一.TCP通讯模板 二.远程CMD程序 三.解决粘包问题 四.解决粘包问题2 一.TCP通讯模板 TCP客户端 import socket c = socket.socket() # 连接服务器 c. ...

  6. Python学习笔记【第十五篇】:Python网络编程三ftp案例练习--断点续传

    开发一个支持多用户在线的FTP程序-------------------主要是学习思路 实现功能点 1:用户登陆验证(用户名.密码) 2:实现多用户登陆 3:实现简单的cmd命令操作 4:文件的上传( ...

  7. python网络编程-TCP服务端的开发

    #TCP服务端开发 2 #方法说明 3 """ 4 bind(host,port)表示绑定端口号,host是ip地址,ip地址一般不进 行绑定,表示本机的任何一个ip地址 ...

  8. Python网络编程 - 一个简单的客户端Get请求程序

    import socket target_host = "www.baidu.com" target_port = 80 # create a socket object clie ...

  9. python 网络编程(Socket)

    # from wsgiref.simple_server import make_server## def RunServer(environ,start_response):# start_resp ...

  10. python 网络编程 TCP/IP socket UDP

    TCP/IP简介 虽然大家现在对互联网很熟悉,但是计算机网络的出现比互联网要早很多. 计算机为了联网,就必须规定通信协议,早期的计算机网络,都是由各厂商自己规定一套协议,IBM.Apple和Micro ...

随机推荐

  1. 1.2 XmlBeanFactory的实例化

    源代码分析,是一件既痛苦又快乐的事情,看别人写的代码是通过的,但当你能够看明白的时候,相信快乐也会随之而来,为了减少痛苦,更快的带来快乐, 本文以spring框架的XmlBeanFactory为入手点 ...

  2. js页面刷新一次

    // var str = document.location.hash, // index = str.indexOf("#"); // if(index == 0){ // wi ...

  3. Struts2自定义拦截器实例—登陆权限验证

    版本:struts2.1.6 此实例实现功能:用户需要指定用户名登陆,登陆成功进入相应页面执行操作,否则返回到登陆页面进行登陆,当直接访问操作页面(登陆后才能访问的页面)时则不允许,须返回登陆页面. ...

  4. 对jQuery.isArray方法的分析

    jQuery.isArray方法应于判断是不是数组,是的话返回true,否则返回false.调用如:jQuery.isArray([]),返回true.其实现源码如下: isArray: Array. ...

  5. 打车APP可能的盈利模式

    贺滨,蓄力的芦苇 竺宇祺.郑子威.党培兵 等人赞同 按现在国内几十家类似start-ups的竞争态势看,嘀嘀现阶段应该还处于烧钱培育市场期. 斗胆想象一下可能的盈利模式: 前向收费(面向用户): 特权 ...

  6. 到底该不该熟悉掌握struts2的ONGL呢?

    其实,在学习网站开发过程中,其实不掌握ONGL也是可以的.我们完全可以使用JSTL和EL来代替OGNL. 只要存在要往页面传输内容,我们直接把对象放在request范围即可,这样我们就可以在jsp中使 ...

  7. hbase命令备忘

    http://www.cnblogs.com/linjiqin/archive/2013/03/08/2949339.html HBase 为用户提供了一个非常方便的使用方式, 我们称之为“HBase ...

  8. jquery ajax 访问webServer的xml文件

    最近项目中要使用到通过ajax访问webServer的xml文件,通过下面的方式可以直接访问webServer的xml文件,不需要在web.xml中进行任何配置.它的返回参数就是服务器上的xml文件. ...

  9. 垃圾收集器GC的种类

    堆内存的结构:

  10. IntelliJ idea 中使用Git

    1.要使用GitHub,首先你需要下载一个Git(地址:http://windows.github.com/)这里使用的是for Windows,然后安装完成会得到如下的一个目录: