python网络编程1

socket编程

 

一、server端和client端通过套接字互相通信(基于TCP)

1.对于服务器端的整个流程:

  1.先创建套接字:sk = socket.socket()

  2.设定ip和port,将套接字绑定在(ip,port)上:sk.bind((ip,port))

  3.进行监听,并设定处理队列中最大的处理连接数:sk.listen(5)

  4.进入while死循环

    1.等待客户端连接服务器端的套接字并返回与客户端连接的套接字conn和ip+port

    2.然后从调用conn.recv(1024)方法,通过套接字conn中接收数据并打印,1次性最大接收1024字节

    3.调用conn.sendall(****)方法,通过套接字conn向客户端发送数据

    4.调用conn.close()方法,关闭套接字  

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket

#定义主机的地址和端口号
ip_port = ('127.0.0.1',999)

#创建socket对象sk
sk =socket.socket()
#将socket绑定到127.0.0.1主机的999端口上
sk.bind(ip_port)
#将此连接套接字接口变成被连接套接字接口,即将此进程设置为服务器进程,可以接受其他请求。
# 5表示已完成服务器连接但服务器未处理的最大进程数量,即等候处理的连接
sk.listen(5)

#设定死循环
while True:

    print "plz waiting...."
    #调用套接字的accept函数接受客户端的主动连接,并返回2个信息:
        # 1.连接至服务器的客户端的套接字conn
        # 2.连接至服务器端的客户端的ip+port,并以元组的形式返回出来
    conn,addr = sk.accept()
    print addr

    #从客户端套接字接收数据,并且每次只能接收最大1024字节
    get_data = conn.recv(1024)
    print get_data
    #通过客户端套接字向客户端发送数据
    conn.send("this is server,hello client")
    #关闭套接字
    conn.close()

 

2.客户端连接的整个流程

  1.创建套接字对象

  2.设置要连接的服务器端的ip和端口port,并调用sk.connect((ip,port))方法进行连接服务器

  3.分别调用sendall()方法和recv()方法进行发送和接收数据

  4.关闭套接字

import socket

#设定要连接的服务器的端口和IP
ip_port = ('127.0.0.1',999)
#创建socket对象sk
sk = socket.socket()
#调用sk.connect(ip_port)连接服务器端
sk.connect(ip_port)
#调用sk.sendall()方法向服务器端发送信息
sk.sendall('this is client,hello server')
#调用sk.recv(1024)方法接收服务器端发来的信息
server_reply = sk.recv(1024)
print server_reply
#关闭套接字
sk.close()

 

二、server端的WEB服务的代码(基于TCP)

server.py

#定义处理请求的函数,传入客户端的套接字
def handle_request(client):
    get_data = client.recv(1024)
    client.send("jachy")
    client.send("HTTP/1.1 200 OK\r\n\r\n")

#定义主函数,用于服务器端的套接字的创建、监听、以及阻塞
def main():
    import socket
    sk = socket.socket()
    ip_port = ('localhost',999)
    sk.bind(ip_port)
    sk.listen(5)

    while True:
        conn,addr = sk.accept()
     #传入监听得到的套接字conn,然后传入请求处理函数,进行对请求进行处理 handle_request(conn) conn.close() if __name__ == "__main__": main()

 

 

三、server端和client端通过套接字互相通信(基于UDP通信)

流程:

  服务器端:

    1.创建基于UDP通信的套接字sk

    2.将套件字绑定在特定端口和IP上,调用sk.bind((ip,port))  【不用像tcp通信一样进行监听,即调用sk.listen(5)】

    3.创建while死循环,等待接收客户端发送的数据,直接调用sk.recv(1024)

    4.关闭套接字

  客户端:

    1.创建基于UDP的套接字对象

    2.向特定套接字发送数据,调用sk.sendto('数据',套接字)

    3.关闭套接字

1.客户端的代码:client.py

import socket
ip_port = ('127.0.0.1',999)
sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
while True:
    inp = raw_input("data:").strip()
    if inp == 'exit':
        break
    sk.sendto(inp,ip_port)
sk.close()

2.服务器端的代码

import socket

sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
ip_port = ('127.0.0.1',999)
sk.bind(ip_port)
#sk.listen(5)  #UDP不用监听套接字,否则会出错

while True:
    data = sk.recv(1024)
    print data

 

简版机器人示例

服务器端:对客户端发过来的信息进行判断,然后对不同的信息采取不同的处理方式

import socket

ip_port = ('127.0.0.1',1111)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)

while True:
    conn,addr = sk.accept()
    conn.sendall('welcome to phone,0 to man ')
    Flag = True
    while Flag:
        print 'plz waiting.....'
        data = conn.recv(1024)
        if data == 'exit':
            Flag = False
        elif data == '0':
            conn.sendall('connect from man')
        else:
            conn.sendall('plz input again:')
    conn.close()

  

客户端:(在客户端对输入的内容进行判断,当输入的是exit时,就自动关闭套接字连接)

import socket

ip_port = ('127.0.0.1',1111)
sk = socket.socket()
sk.connect(ip_port)
sk.settimeout(5)

while True:
    data = sk.recv(1024)
    print "receieve :",data
    inp = raw_input("plz input :").strip()
    sk.sendall(inp)
    if inp == "exit":
        break
sk.close()

 

 

四、基于SocketServer多线程处理并发

server.py

import SocketServer

#定义MyServer类,继承BaseRequestHandler类,请求处理 class MyServer(SocketServer.BaseRequestHandler): #定义处理对象函数 def handle(self): #得到客户端的套接字conn conn = self.request #向客户端套接字发送信息 conn.sendall("welcome to phone 10086,0 to man ,1 to work") #设定标志位,为当收到exit信息时,跳出循环做准备 Flag = True while Flag: data = conn.recv(1024) if data == "exit": Flag = False elif data == "0": conn.sendall("connect to people") else: conn.sendall("plz input again:") if __name__ == "__main__": ip_port = ('127.0.0.1',8009) #传入特定地址的套接字和处理方法,创建多线程处理服务器对象 server = SocketServer.ThreadingTCPServer(ip_port,MyServer) #调用对象的serve_forever方法 server.serve_forever()

 

client.py

import socket
sk = socket.socket()
ip_port = ('127.0.0.1',8009)
sk.connect(ip_port)
#设置阻塞模式下socket的超时时间为5s,socket的后续操作若在给定超时时间内没完成,将触发timeout异常
sk.settimeout(5)

while True:
    get_data = sk.recv(1024)
    print "get data %s" %get_data
    inp = raw_input("plz input:").strip()
    sk.sendall(inp)
    if inp == "exit":
        break
sk.close()

观察效果方法:

  1.运行server.py,让server处于监听状态

  2.运行多个client.py,使得多个客户端去连接服务器,即让服务器处理多个客户端的请求

 

五、基于socket、threading、select模块实现并发、多线程处理多个连接请求

  select--用于异步阻塞,实现非阻塞I/O

  threading---用于多线程处理请求

import socket
import threading
import select

def process(request,client_address):
    print request,client_addr
    conn = request
    conn.sendall("welcome to phone 10086")
    flag = True

    while flag:
        data = conn.recv(1024)
        if data == "exit":
            flag = False
        elif data == "0":
            conn.sendall("connect to man service")
        else:
            conn.sendall("plz input again")


sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip_port = ('127.0.0.1',8002)
sk.bind(ip_port)
sk.listen(5)

while True:
    #select模块以列表的形式接收4个参数:
        #1.需要监控的可读文件(套接字)对象,list类型
        #2.可写文件文件对象,list类型
        #3.产生异常的文件对象,list类型
        #4.超时设置
    返回3个对象:  
      #1.读事件,list类型
      #2、写事件,list类型
      #3、异常对象,list类型
rs, ws,es =select.select([sk,],[],[],1) print "looping" #判断sk是否是本机上用于监听的socket if sk in rs: print 'get request' request和client_addr分别是接收到的socket对象和地址+端口 request,client_addr = sk.accept() #创建线程对象,接收处理线程处理函数,参数是端口+ip t = threading.Thread(target=process,args=(request,client_addr)) t.daemon = False #开始线程活动 t.start() sk.close()

 

 

posted @ 2015-12-17 22:58  杰希  阅读(210)  评论(0编辑  收藏  举报