Python下基于Sokcet的TCP通信

TCP/UDP协议均为传输层的协议,绝大部分应用程序之间的通信都是使用TCP或UDP,故而在网络通信中及其重要,想详细了解他们之间的差异,可参考

1.模拟后台程序,实现浏览器访问

Server端代码

# coding=utf-8 import socket def handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n") # 此句允许浏览器访问 client.send("Hello, TCP Socket ") # 发送要显示的内容 def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 8090)) # 设定ip(或者域名)和端口号 sock.listen(2) # 设置最大并发数 while 1: conn, address = sock.accept() # 接收请求 handle_request(conn) # 处理请求 conn.close() # 关闭连接 if __name__ == '__main__': main() 

使用浏览器访问 localhost:8090

2.模拟机器猫程序(客户端发送信息,从服务端返回源数据)

A. ServerTCP.py代码

# coding=utf-8 import socket def handle_request(conn): conn.send("server: hello, let's start ") flag = True while flag: data = conn.recv(1024) if data == 'exit': flag = False else: conn.sendall(data) def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 8091)) # 设定ip(或者域名)和端口号 sock.listen(2) # 设置最大并发数 while 1: conn, address = sock.accept() # 接收请求 print address, handle_request(conn) # 处理请求 conn.close() # 关闭连接 if __name__ == '__main__': main()

B.ClientTCP.py

# coding:utf-8 import socket client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) address = ('localhost', 8091) client.connect(address) while 1: data = client.recv(1024) # client.send('client: ok, let\'s begin ') print data inp = raw_input('client:') client.send(inp) if inp == 'exit': # 输入exit,退出 break 

C.两程序交互结果

  3.socket模块中的socket类简要分析

conn = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

参数一:地址类型

  socket.AF_INET, 表示使用IPv4类型的IP, 默认类型

  socket.AF_INET6, 表示使用IPv6类型的IP

  socket.AF_UNIX, 表示使用Unix系统中同一台设备中两进程通信的socket

参数二:数据包格式

  socket.SOCK_STREAM  流式socket , for TCP (默认)

  socket.SOCK_DGRAM   数据报式socket , for UDP

  socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。

  socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。

  socket.SOCK_SEQPACKET 可靠的连续数据包服务

socket.bind(address)

  固定地址,地址包括主机和端口。主机可使用ip或域名标识。

socket.listen(backlog)

  设置最最大并发数

socket.connect(address)/socket.connect_ex(address)

  客户端请求建立连接,address表示地址,两者的区别是,如果连接出现异常,前者直接报出异常,后者返回错误码,程序继续运行

conn, address = socket.accept()

  服务端接收请求建立起连接,返回连接和地址。

socket.close()

  关闭连接

sk.recv(bufsize[,flag])

  接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。

sk.recvfrom(bufsize[.flag])

  与recv()类似,但返回值是(data,address)。

sk.send(string[,flag])

  将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。

sk.sendall(string[,flag])

  将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

内部通过递归调用send,将所有内容发送出去。

sk.sendto(string[,flag],address)

  将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/697a566fe9c85a9dfeb84395fd235405.html