TCP编程
Socket是网络编程的一个抽象概念,通常我们用一个Socket表示“打开了一个网络连接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,在指定协议类型即可。
客户端
大多数连接就是考的TCP连接。创建TCP连接时,主动发起连接叫客户端,被动响应练级的叫服务器。
举个栗子,当我们在浏览器中访问新浪时,我们自己的计算机就是客户端,浏览器会主动向新浪的服务器发起连接,如果一切顺利,新浪的服务器接收了我们的连接,一个TCP连接就建立起来了,后面的通信就是发送网页内容了。
所以,我们要创建一个基于TCP连接的Socket,可以这样做:
# 导入socket库
import socket #创建一个socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 建立连接
s.connent(('www.sina.com.cn', 80))
创建Socket是,AF_INET 指定使用IPv4协议,吐过要用更先进的IPv6,就指定为AF_INET6.SOCK_STREAM指定使用面向流的TCP协议,这样,一个Socket对象就创建成功,但是还没有建立连接。
客户端要主动发起TCP连接,必须知道服务器的IP地址和端口号,新浪网站的IP地址可以用域名www.sina.com.cn 自动转到IP地址,但是怎么知道新浪的端口号呢?
答案是作为服务器,提供什么样的服务,端口就必须固定下来,由于我们想要访问网页,因此新浪提供网页服务的服务器必须把端口号固定在80端口,因为80端口是Web服务器的标准端口。其他服务都有对应服务的端口号,例如SMTP服务是25端口,FTP服务是21端口,等等。端口号小于1024的是internet标准服务的端口,端口号大于1024的,可以任意使用。
因此,我们连接新浪服务器的代码如下:
s.connect(('www.sina.com.cn', 80))
注意参数是一个tuple,包涵地址和端口号。
建立TCP连接后,我们就可以向新浪服务器发送请求,要求返回首页的内容:
# 发送数据
s.send(b'GET / HTTP/1.1\R\nHost: www.sona.xom.cn\r\nConnection: close\r\n\r\n')
TCP连接创建的是双向通道,双向搜可以同时给对方发数据。但是谁先发谁后发,怎么协调,要根据具体的协议来决定。例如,HTTP协议规定客户端必须先发送请求给服务器,服务器收到后才发数据给客户端。
发送的文本格式必须符合HTTP标准,如果格式没问题,接下来就可以接受新浪服务器返回的 数据了:
# 接受数据
buffer = []
while True:
# 每次最多接收1k字节
d = s.reav(1024)
if d:
buffer.append(d)
else:
break data = b''.join(buffer)
接收数据时,调用recv(max)方法,一次最多接收指定的字节数,因此,在一个while循环里面反复接收,直到recv()返回空数据,表示接收完毕,退出循环。
当我们接收完数据后,调用close()方法关闭Socket,这样,一次完整的网络通信就结束了;
# 关闭连接
s.close()
接收到的数据包括HTTP头和网页本身,饿哦们只需要把HTTP头和网页分离一下,把HTTP头打印出来
件:
header, html = data.split(b'\r\n\r\n', 1)
print(header.decode('utf-8'))
# 把接收的数据写入文件
with open('sina.html', 'wb') as f:
f.write(html)
现在,只需要在浏览器中打开这个dina.html文件,就可以看到新浪首页了。
服务器
和客户端编程相比,服务器变成就要复杂一些。
服务器进程首先要绑定一个端口并监i,听来自其他客户端的连接,如果某个客户端连接进来了,服务器就与改客户端建立Socket连接,随后的通信就靠这个Socket连接了。
所以,服务器会打开固定端口(比如80)监听,每来一个客户端连接,就创建给Socket连接。由于服务器会大量来自客户端的连接,所以,服务器要能够区分一个Socket连接是和那个客户段绑定的。一个Socket依赖4项:服务器地址,服务器端口,客户端地址,客户端端口来唯一确定一个Socket。
但是服务器还需要同时响应多个客户端的请求,所以,每个连接都需要一个新的进程或者线程来处理,否则,服务器一次就只能服务器一个客户端了。
我们来编写一个简单的服务器程序,它接收客户点连接,把客户端发过来的字符串加上Hello在发回去。
首先,创建一个基于IPv4和TCP协议的Socket;
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
然后,我们要绑定监听的地址和端口。服务器可能有多快网卡,可以绑定到某一块网卡的IP地址上,也可以用0.0.0.0绑定到所有的网络地址,还可以用127.0.0.1绑定到本机地址。127.0.01是一个特殊的IP地址,表示本机地址,如果绑定到这个地址,客户端必须同时在本机运行才能连接,也就是说,外部的计算机无法连接进来。
端口号需要预先指定。因为我们写的这个服务不是标准的服务,所以用9999这个端口。请注意。小于1024的端口号必须要有管理员权限才能绑定;
# 监听端口
s.bind('127.0.0.1', 9999)
紧接着,调用listen()方法开始监听端口,传入的参数指定等待连接的自大数量:
s.listen(5)
print('Waiting for connection...')
接下来,服务器程序通过一个永久循环来接受来自客户端的连接,accept()会等待返回一个客户端的连接:
while True;
# 接受一个新连接
sock, addr = s.accept()
# 创建新线程来处理TCP连接:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()
每个连接都必须创建新线程(或进程)来处理,否则,单线程在处理连接的过程中,无法接受其他客户端的连接:
def tcplink(sock, addr):
print('Accept new connection from %s: %s...'% addr)
sock.send(b'Welcome!')
while True;
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data.decode('utf-8')) .encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.'% addr)
建立连接后,服务器首先发一条欢迎消息,然后等待客户数据,并加上Hello再发送给客户端。如果客户端发送了exit字符串,就直接关闭连接。
要测试这个服务器程序,我么还需要编写一个客户端程序:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接
s.connect(('127.0.0.1', 9999))
#接收欢迎消息
print(s.recv(1024).decode('utf-8'))
for data in in [b'Michael', b'Tracy', b'Sarch']
# 发送数据
s.send()
print(s.recv(1024).decode('utf-8'))
s.send(b'text')
s.close()
我们需要打开两个命令窗口,一个运行服务器程序,另一个运行客户端程序,就可以看到结果了:
需要注意的是,客户端程序运行完毕就退出了,而服务器程序会永远运行下去,必须按Ctrl+C退出程序。
小结
用TCP协议进行Socket编程在Python中十分简单,对于客户端,要主动链接服务器的IP和指定端口,对于服务器,要首先监听指点端口,然后对每一个新的连接,创建一个线程或进程来处理,通常,服务器程序会无线运行下去。
同一个端口,被一个Socket绑定了以后,就不能被别的Socket绑定了。
TCP编程的更多相关文章
- Java TCP编程
Java编写TCP编程--回射信息实例 注:简单的tcp联系,还存在问题,readUTF()为阻塞型,如果之前的用户一直不输入,则一直阻塞,之后的用户再连接会出现问题. import java.io. ...
- [C# 网络编程系列]专题五:TCP编程
转自:http://www.cnblogs.com/zhili/archive/2012/08/25/2656840.html 前言 前面专题的例子都是基于应用层上的HTTP协议的介绍, 现在本专题来 ...
- python中的TCP编程学习
今天看了一下关于python的TCP编程. 发现思路和其他语言(比如java)思路基本上差点儿相同. 先看client.基本过程例如以下: 第一步:创建一个socket 第二步:建立连接 第三步:发送 ...
- C#网络程序设计(3)网络传输编程之TCP编程
网络传输编程指基于各种网络协议进行编程,包括TCP编程,UDP编程,P2P编程.本节介绍TCP编程. (1)TCP简介: TCP是TCP/IP体系中最重要的传输层协议,它提供全双工和可 ...
- 【Socket编程】通过Socket实现TCP编程
通过Socket实现TCP编程 Socket通信 : 1.TCP协议是面向对象连接.可靠的.有序的,以字节流的方式发送数据. 2.基于TCP协议实现网络通信的类: 客户端----Socket类 服务器 ...
- JAVA 通过 Socket 实现 TCP 编程
简介 TCP简介 TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的.可靠的.基于字节流的传输层通信协议,由IETF的RFC 793定义.在简化的计算机 ...
- 网络编程之TCP编程
网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...
- 在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来
在做关于NIO TCP编程小案例时遇到无法监听write的问题,没想到只是我的if语句的位置放错了位置,哎,看了半天没看出来 贴下课堂笔记: 在Java中使用NIO进行网络TCP套接字编程主要以下几个 ...
- 五十四、linux 编程——TCP 编程模型
54.1 编程模型介绍 54.1.1 TCP 客户端服务器编程模型 客户端调用序列 调用 socket 函数创建套接字 调用 connect 连接服务器端 调用 I/O 函数(read/write) ...
- Linux C Socket TCP编程介绍及实例
转自:https://blog.csdn.net/lell3538/article/details/53335231 { printf("向服务器发送数据:%s\n",sendbu ...
随机推荐
- 如何在Windows命令行(DOS界面)中调用 编译器 来编译C/C++源程序
首先说明一下背景: 为什么要在DOS界面编译C/C++源程序?有很多现成的开发环境(IDE)如:vs, vc++等,这些开发环境集成了编译,调试,使用起来很方便,而且图形化操作界面,简洁明了.但是在开 ...
- jekins构建触发器详解-日程表的使用
日程表参数解释如下: 第一个参数代表的是分钟 minute,取值 0~59: 第二个参数代表的是小时 hour,取值 0~23: 第三个参数代表的是天 day,取值 1~31: 第四个参数代表的是月 ...
- 【spring】之xml和Annotation,Bean注入的方式
基于xml形式Bean注入 @Data @AllArgsConstructor @NoArgsConstructor public class PersonBean { private Integer ...
- Android中是否推荐使用枚举Enum
一.Enum的产生 Java1.5中引入了枚举的语法,包括Enum,EnumSet,EnumMap等.其中Enum就是我们在C或C++中见过的枚举类型,但是Java中的枚举又比C或C++中的枚举更成熟 ...
- PAT 甲级 1083 List Grades (25 分)
1083 List Grades (25 分) Given a list of N student records with name, ID and grade. You are supposed ...
- 20175227张雪莹 2018-2019-2 《Java程序设计》第三周学习总结
20175227张雪莹 2018-2019-2 <Java程序设计>第三周学习总结 教材学习内容总结 (仅在此列举个性化学习总结) 一.编程语言的几个发展阶段. 1.面向机器语言:汇编语言 ...
- py库:把python打包成exe文件(pyinstaller)
http://blog.csdn.net/be_quiet_endeavor/article/details/73929077 用Pyinstaller把Python3.4程序打包成可执行文件exe ...
- gdb 使用
2018年7月27日21:05:16 —— 多进程调试 1.follow_fork_mode 作用:在fork之后跟随父进程还是子进程 可以使用 show follow_fork_mode查看再for ...
- 编程最好用的字体consolas
python 自带idle最好用的字体consolas https://www.icourse163.org/learn/BIT-268001?tid=1002788003#/learn/forumd ...
- This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.
This iPhone 6s is running iOS 11.3.1 (15E302), which may not be supported by this version of Xcode.