connection, address = socket.accept()

调 用accept方法时,socket会时入“waiting”状态。客户请求连接时,方法建立连接并返回服务器。accept方法返回一个含有两个元素的 元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。
第五步是处理阶段,服务器和客户端通过send和recv方法通信(传输 数据)。服务器调用send,并采用字符串形式向客户发送信息。send方法返回已发送的字符个数。服务器使用recv方法从客户接收信息。调用recv 时,服务器必须指定一个整数,它对应于可通过本次方法调用来接收的最大数据量。recv方法在接收数据时会进入“blocked”状态,最后返回一个字符 串,用它表示收到的数据。如果发送的数据量超过了recv所允许的,数据会被截短。多余的数据将缓冲于接收端。以后调用recv时,多余的数据会从缓冲区 删除(以及自上次调用recv以来,客户可能发送的其它任何数据)。
传输结束,服务器调用socket的close方法关闭连接。
python编写client的步骤:

举例:

服务端:

#socket server端
#获取socket构造及常量
from socket import *
#''代表服务器为localhost
myHost = ''
#在一个非保留端口号上进行监听
myPort = 50007

#设置一个TCP socket对象
sockobj = socket(AF_INET, SOCK_STREAM)
#绑定它至端口号
sockobj.bind((myHost, myPort))
#监听,允许5个连结
sockobj.listen(5)

#直到进程结束时才结束循环
while True:
    #等待下一个客户端连结
    connection, address = sockobj.accept( )
    #连结是一个新的socket
    print 'Server connected by', address
    while True:
        #读取客户端套接字的下一行
        data = connection.recv(1024)
        #如果没有数量的话,那么跳出循环
        if not data: break
        #发送一个回复至客户端
        connection.send('Echo=>' + data)
    #当socket关闭时eof
    connection.close( )

客户端:

import sys
from socket import *
serverHost = 'localhost'
serverPort = 50007

#发送至服务端的默认文本
message = ['Hello network world']
#如果参数大于1的话,连结的服务端为第一个参数
if len(sys.argv) > 1:
    serverHost = sys.argv[1]
    #如果参数大于2的话,连结的文字为第二个参数
    if len(sys.argv) > 2:
        message = sys.argv[2:]

#建立一个tcp/ip套接字对象
sockobj = socket(AF_INET, SOCK_STREAM)
#连结至服务器及端口
sockobj.connect((serverHost, serverPort))

for line in message:
    #经过套按字发送line至服务端
    sockobj.send(line)
    #从服务端接收到的数据,上限为1k
    data = sockobj.recv(1024)
    #确认他是引用的,是'x'
    print 'Client received:', repr(data)

#关闭套接字
sockobj.close( )

参考:

http://blog.sina.com.cn/s/blog_523491650100hikg.html

 创建一个socket客户端 

#coding:utf-8
#导入相关模块
import socket
import sys #设置连接请求30S超时
socket.setdefaulttimeout(30) #IPV4协议、字节流(TCP协议)
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
except socket.error as e:
print 'Socket Error:%s'%(str(e))
sys.exit()
print 'Socket Created!' host = 'www.baidu.com'
port = 80 #获取IP地址
try:
remote_ip = socket.gethostbyname(host) #此处同PHP中的gethostbyname()函数
except socket.gaierror as e:
print 'get %s ip error %s'%(host,str(e))
sys.exit() print 'Ip address of %s is %s'%(host,remote_ip) #连接服务器(SOCK_STREAM/TCP 套接字才有“连接”的概念,一些 Socket 如 UDP、ICMP 和 ARP 没有“连接”的概念)
try:
s.connect((remote_ip,port))
except Exception as e:
print 'Socket Connect to %s:%s Faile!!Error:%s'%(host,port,str(e))
sys.exit()
print 'Socket Connect to %s on ip %s'%(host,remote_ip) #发送数据(根据HTTP/1.1协议)
# 请求消息的结构如下
# 请求方法 路径 HTTP版本\r\n ------>这为请求行
# 请求头域1: 请求头域的值1\r\n
# 请求头域2: 请求头域的值2\r\n
# ........................ ------->以上行为请求头
# 一个空行\r\n -------->头与主体间的空行
# 请求主体...... -------->请求主体
#
#########
#请求行(方法)
msg = "GET / HTTP/1.1\r\n"
#请求header(HTTP/1.1请求必须包含主机头域,否则系统会以400状态码返回)
msg+= "Host: baidu.com\r\n"
#空行
msg+= "\r\n"
#请求body(由于我们这里是GET请求所以,body没有) try:
#这里也可用send()方法:不同在于sendall在返回前会尝试发送所有数据
#并且成功时返回是None,而send()则返回发送的字节数量。失败时都抛出异常。
s.sendall(msg)
except Exception as e:
print 'Send Failed!'
sys.exit()
print 'Msg Send Successfully!' #获取服务器返回的数据
respone = s.recv(4096) #这里还可用recvfrom()、recv_into()等等
print respone #释放资源
s.close()

输出:

Socket created
ip address of www.baidu.com is 115.239.210.26
Msg Send successfully!
HTTP/1.1 200 OK
Date: Fri, 21 Feb 2014 05:32:29 GMT
Content-Type: text/html
Transfer-Encoding: chunked
Connection: Keep-Alive
Vary: Accept-Encoding
Set-Cookie: BAIDUID=0D5536687056DF9F5C088AFBE27E42B7:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
Set-Cookie: BDSVRTM=7; path=/
Set-Cookie: H_PS_PSSID=4850_1432_5186_5198_4261_5260_4760_5208; path=/; domain=.baidu.com
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Expires: Fri, 21 Feb 2014 05:32:29 GMT
Cache-Control: private
Server: BWS/1.1
BDPAGETYPE: 1
BDQID: 0x95f7c521930a6c8e
BDUSERID: 0

为什么没有输出全部数据呢?看下面的函数:

socket.recv(bufsize[, flags])

Receive data from the socket. The return value is a string representing the data received. The maximum amount of data to be received at once is specified by bufsize. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.

Note

For best match with hardware and network realities, the value of bufsize should be a relatively small power of 2, for example, 4096.

输出不完整。一些数据被漏掉。在TCP/IP协议下上面的情况会发生。在这个协议,数据以块进行传输。例如一个网页是500kb,但是最大快只有64kb。因此传输网页时,一次只传输了一部分而不是全部。
 
这就是问题产生的原因。recv函数能够等待直到收到所有的数据,但是对此,它必须知道整个要传输数据的大小。s.recv(4096 , socket.MSG_WAITALL) 会等待直到得到整个4096 bytes。现在如果实际响应的大小小于这个尺寸,函数会被阻塞一段时间,直到它返回。这不是我们所期待的。 
解决:
解决方法是保持查询数据直到一个适当的超时发生,下面的例子中,我们就是这么做的:
def recv_timeout(the_socket,timeout=2):
#make socket non blocking
the_socket.setblocking(0) #total data partwise in an array
total_data=[];
data=''; #beginning time
begin=time.time()
while 1:
#if you got some data, then break after timeout
if total_data and time.time()-begin > timeout:
break #if you got no data at all, wait a little longer, twice the timeout
elif time.time()-begin > timeout*2:
break #recv something
try:
data = the_socket.recv(8192)
if data:
total_data.append(data)
#change the beginning time for measurement
begin=time.time()
else:
#sleep for sometime to indicate a gap
time.sleep(0.1)
except:
pass #join all parts to make final string
return ''.join(total_data)
步骤是:
1.保证socket非阻塞。对此,socket不会等待,如果在recv调用没有数据。它会继续,如果没有数据可用。
2.按下面方式循环:保持调用recv,直到一个超时发生或recv完成。
 
现在这是一个简单的方法来证明recv函数在实际的应用中该如何工作。同样的函数能够进一步开发,然后变得更复杂,根据工作的协议,例如HTTP。
 
创建一个socket服务器端
#coding:utf-8
import socket
import sys
import time
import Queue
import threading host = 'localhost'
port = 8000 #创建socket对象
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #绑定一个特定地址,端口
try:
s.bind((host,port))
except Exception as e :
print 'Bind Failed:%s'%(str(e))
sys.exit()
print 'Socket bind complete!!' #监听连接
s.listen(10) #最大连接数10 #创建连接队列
queue = Queue.Queue() #创建线程
class TaskThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self) def run(self):
while 1:
t = queue.get()
t.send('welecome.....')
#接收数据
client_data = t.recv(1024)
t.sendall(client_data)
#释放资源
#t.close() #接受连接
while 1: #将连接放入队列
conn,addr = s.accept()
print 'Connected from %s:%s'%(addr[0],str(addr[1]))
queue.put(conn) #生成线程池
th = TaskThread()
th.setDaemon(True)
th.start() queue.join()
s.close()

以上例子参考于: http://www.oschina.net/question/12_76126?sort=default&p=2#answers

Python socket 客户端和服务器端的更多相关文章

  1. socket客户端和服务器端

    服务器端: #!/usr/bin/env python #-*- coding:utf-8 -*- import socket sk=socket.socket() sk.bind(('127.0.0 ...

  2. Python Socket 网络编程 (服务器端编程)

    服务器端主要做以下工作: 打开 socket 绑定到特定的地址以及端口上 监听连接 建立连接 接收/发送数据 上面已经介绍了如何创建 socket 了,下面一步是绑定. 绑定 socket 函数 bi ...

  3. php socket客户端及服务器端应用实例

    经常有朋友会对php的socket应用充满疑惑,本文就以实例代码作一讲解,希望能对初学php的朋友起到一点帮助作用 具体代码如下: 1.服务器端代码: <?php class SocketSer ...

  4. python socket客户端

    #./usr/bin/env python#coding:utf-8import socket#.....ip...print ('server start...')ip_port = ('144.3 ...

  5. 170925_1 Python socket 创建TCP的服务器端和客户端

    [Python版本]3.6 [遇到的问题] 客户端和服务器端都遇到:TypeError: a bytes-like object is required, not 'str' [解决方案] 参考:ht ...

  6. Socket编程——客户端,服务器端的读写操作

    URL网络编程,最大的特征就是一对一的响应! 1:客户端“写”,服务器端用于“读” package coreBookSocket2; import java.io.InputStreamReader; ...

  7. python socket之tcp服务器与客户端demo

    python socket之tcp服务器与客户端demo 作者:vpoet mails:vpoet_sir@163.com server: # -*- coding: cp936 -*- ''' 建立 ...

  8. python--DenyHttp项目(1)--socket编程:客户端与服务器端

    查找了许多资料,实现了客户端与服务器端的连接,通过虚拟机进行测试 服务器端IP:192.168.37.129 端口1122 客户端IP: 192.168.37.1 端口1122 Server: #co ...

  9. Python socket的客户端

    做一个socket客户端1.声明一个实例2.绑定端口号和地址3.循环发送和接收响应其中要注意粘包的产生,为了防止粘包的产生,应该在服务器端先测出要发送信息的大小,然后发送响应至客户端,等到服务器上一条 ...

随机推荐

  1. OpenStack Summit Paris 会议纪要 - 11-04-2014

    前言: 来源:https://wiki.openstack.org/wiki/Summit/Kilo/Etherpads#Ops 不一定翻译准.由于是在summit上随手写的. 重点关注Ops Sum ...

  2. [Angular 2] Rendering an Observable Date with the Async and Date Pipes

    Instead of simply pushing numbers on a timer into the template, now we'll move on to pushing actual ...

  3. Android开发系列之button事件的4种写法

    经过前两篇blog的铺垫,我们今天热身一下,做个简单的样例. 文件夹结构还是引用上篇blog的截图. 详细实现代码: public class MainActivity extends Activit ...

  4. Chapter 4. Using the Gradle Command-Line 使用gradle命令行

    This chapter introduces the basics of the Gradle command-line. You run a build using the gradle comm ...

  5. POJ 2976 Dropping tests 01分数规划

    给出n(n<=1000)个考试的成绩ai和满分bi,要求去掉k个考试成绩,使得剩下的∑ai/∑bi*100最大并输出. 典型的01分数规划 要使∑ai/∑bi最大,不妨设ans=∑ai/∑bi, ...

  6. NOI2015 程序自动分析

    /* 十分简单的题面 离散化一下 然后并茶几一下就OK了 跑的死慢 可能还有更优的方法吧 */ #include<iostream> #include<cstdio> #inc ...

  7. 8、第八次课jquery第一节20151006

    1.JS JQUERY 的区别 jquery 底层基于js 它是对于JS进行封装,代码量比较少.[write less do more] 网上可以下载jquery 类库文件,写的时候需要智能提示在js ...

  8. nyoj 214

    //nyoj 214 这个题目和字符串的问题类似,都是给出一组数据,寻找最长的单调递增字符 这一题一开始我用dp做,发现超时,看了下时间,n*n的复杂度,换过一种思路 用类似于栈的方式,来存储每次更新 ...

  9. ASP.Net页面间传值

    一.目前在ASP.NET中页面传值共有这么几种方式: 1.表单提交,   <form action= "target.aspx" method = "post&qu ...

  10. angularjs directive中@ = &使用详解

    这段时间在学习angularjs,对directive指令的绑定策略弄了好久才明白,现在做下笔记方便以后查阅,若有错误欢迎指出. 为了使新的指令作用域能访问当前的作用域的一些属性,通常会使用@.=.& ...