python_socket

Socket

  • socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】。

 

 1 #!/usr/bin/env python
 2 #coding=utf-8
 3 __author__ = 'yinjia'
 4 
 5 
 6 import socket
 7 
 8 ip_port = ('127.0.0.1',9999)
 9 
10 sk = socket.socket()
11 sk.bind(ip_port)
12 sk.listen()
13 
14 while True:
15     print("等待连接......")
16     con,addr = sk.accept()
17 
18     client_data = str(con.recv(1024),encoding='utf-8')
19     print(client_data)
20     con.sendall(bytes("不想回答!",encoding='utf-8'))
21 
22     con.close()
server
 1 #!/usr/bin/env python
 2 #coding=utf-8
 3 __author__ = 'yinjia'
 4 
 5 
 6 import socket
 7 
 8 ip_port = ('127.0.0.1',9999)
 9 
10 sk = socket.socket()
11 sk.connect(ip_port)
12 
13 sk.sendall(bytes("您好,请回答问题!",encoding='utf-8'))
14 
15 server_reply = sk.recv(1024)
16 print(str(server_reply,encoding='utf-8'))
17 
18 sk.close()
client
  • sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
 1 参数一:地址簇
 2 
 3   socket.AF_INET IPv4(默认)
 4   socket.AF_INET6 IPv6
 5 
 6   socket.AF_UNIX 只能够用于单一的Unix系统进程间通信
 7 
 8 参数二:类型
 9 
10   socket.SOCK_STREAM  流式socket , for TCP (默认)
11   socket.SOCK_DGRAM   数据报式socket , for UDP
12 
13   socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
14   socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
15   socket.SOCK_SEQPACKET 可靠的连续数据包服务
16 
17 参数三:协议
18 
19   0  (默认)与特定的地址家族相关的协议,如果是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议

SocketServer

  • SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端。即:每个客户端请求连接到服务器时,Socket服务端都会在服务器是创建一个“线程”或者“进程” 专门负责处理当前客户端的所有请求。

 

ThreadingTCPServer实现的Soket服务器内部会为每个client创建一个 “线程”,该线程用来和客户端进行交互。

 1 #!/usr/bin/env python
 2 #coding=utf-8
 3 __author__ = 'yinjia'
 4 
 5 import socketserver
 6 
 7 class MyServer(socketserver.BaseRequestHandler):
 8 
 9     def handle(self):
10         conn = self.request
11         teacher = "老师说:"
12 
13 
14         conn.sendall(bytes('欢迎使用选课系统!', encoding='utf-8'))
15         #连接客户端地址信息
16         while True:
17             print("server waiting...")
18             ret_bytes = conn.recv(1024)
19             ret_str = str(ret_bytes,encoding='utf-8')
20             if ret_str.lower() == 'q':
21                 break
22             conn.sendall(bytes(teacher + '',encoding='utf-8'))
23 
24 if __name__ == '__main__':
25     server = socketserver.ThreadingTCPServer(('127.0.0.1',9999),MyServer)
26     server.serve_forever()
服务端
 1 #!/usr/bin/env python
 2 #coding=utf-8
 3 __author__ = 'yinjia'
 4 
 5 
 6 import socket
 7 ip_port = ('127.0.0.1',9999)
 8 
 9 
10 sk = socket.socket()
11 sk.connect(ip_port)
12 
13 ret_bytes = sk.recv(1024)
14 ret_str = str(ret_bytes,encoding='utf-8')
15 print(ret_str)
16 
17 while True:
18     inp = str(input("发送:"))
19     if inp.lower() == 'q':
20         sk.sendall(bytes(inp,encoding='utf-8'))
21         break
22     else:
23         sk.sendall(bytes(inp,encoding='utf-8'))
24         ret = str(sk.recv(1024),encoding='utf-8')
25         print(ret)
26 sk.close()
客户端

ForkingTCPServer和ThreadingTCPServer的使用和执行流程基本一致,只不过在内部分别为请求者建立 “进程”  和 “线程”。

ForkingTCPServer只是将 ThreadingTCPServer 实例中的代码如下:

1 server = socketserver.ThreadingTCPServer(('127.0.0.1',9999),MyServer)
2 变更为:
3 server = socketserver.ForkingTCPServer(('127.0.0.1',9999),MyServer)

 其实本质上就是在服务器端为每一个客户端创建一个进程,当前新创建的进程用来处理对应客户端的请求,所以,可以支持同时n个客户端链接(长连接)。

posted on 2018-04-20 10:22  Jasongo  阅读(259)  评论(0编辑  收藏  举报