创建一个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.
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)
#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