python下基于sokcet的tcp通信——入门篇

时间:2024-10-13 23:36:38

环境

python版本:2.7

IDE:pycharm

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

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

Server端代码

# coding=utf-
import socket def handle_request(client):
buf = client.recv()
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', )) # 设定ip(或者域名)和端口号
sock.listen() # 设置最大并发数 while :
conn, address = sock.accept() # 接收请求
handle_request(conn) # 处理请求
conn.close() # 关闭连接 if __name__ == '__main__':
main()

使用浏览器访问 localhost:8090

python下基于sokcet的tcp通信——入门篇

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

A. ServerTCP.py代码

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

B.ClientTCP.py

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

C.两程序交互结果

python下基于sokcet的tcp通信——入门篇

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协议。