700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > TCP/IP协议学习笔记(二)

TCP/IP协议学习笔记(二)

时间:2023-03-26 00:26:16

相关推荐

TCP/IP协议学习笔记(二)

工程建立:

先建Project然后添加module和package,如图所示:

代码编写:

首先代码中会出现中文字符,所以要在代码中添加#coding utf-8,避免出现乱码。

然后明确TCP/IP协议需要哪些类与方法:

baseserver--->tcpserver-->threadingmixserver

按照顺序进行编写:

TCPServer 继承于 TheadingTCPServer类,按住ctrl阅读TheadingTPServer这个类 :

发现TheadingTCPServer继承于ThreadingMixIn和TCPServer,同样按住ctrl点击TCPServer进行阅读,里面有具体的实现,初始化的方法。

然后,定义一个类,继承于socketserver里的一个类StreamRequestHandler点鼠标右键里面有一个重载方法Override实现setup就可以了。

最后,写测试代码判断是否能够流畅运行:

使用元祖来规定输出的格式,address是一个元祖用括弧括起来的。实现Tserver,接收address,使用我们定义的ClientRequestHandler进行处理,修改间隔时间,点击运行。

运行TCP/IP代码:

在eclipse里点击Run as,按win+R进入命令行模式,输入telnet 192.168.1.2,远程登录,完成实验

学习反思:

学习中遇到的问题:

1.输入端口号错误,导致套接字重复报错,经过查询,23号端口为Telnet端口,修改代码。

2.重载是什么?

答:重载就是方法名相同,参数(个数或类型)不同(称之为签名不同)

比如:

string test()

{

Console.WriteLine("Hello world");

}

string test(string msg)

{

Console.WriteLine(msg);

}

这样就达到了,用同样的方法名,通过传递不同的参数,实现不同的目的 。

3.继承怎么使用?

答:继承是指一个对象直接使用另一对象的属性和方法。事实上,我们遇到的很多实体都有继承的含义。例如,若把汽车看成一个实体,它可以分成多个子实体,如:卡车、公共汽车等。这些子实体都具有汽车的特性,因此,汽车是它们的"父亲",而这些子实体则是汽车的"孩子"。如果一个类A继承自另一个类B,就把这个A称为"B的子类",而把B称为"A的父类"。继承可以使得子类具有父类的各种属性和方法,而不需要再次编写相同的代码。在令子类继承父类的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类的原有属性和方法,使其获得与父类不同的功能。

关于服务器端的完善和客户端的编写:

在之前的服务器端里只是重载了setup方法并没有对数据的处理,为了完善服务器端的功能将重载方法改为handle进行处理。然后定义一个清单,便于用户连接,当用户连接,进入循环获取他们的套接字,也就是他们的IP地址和端口号。并且通过self.wfile.write给客户端返回一个字符串,如果客户端向服务器端发送121的请求,通过self.rfile.read来获取并显示已获取。

'''Created on 9月25日@author: 15006'''from socketserver import ThreadingTCPServer, StreamRequestHandlerfrom multiprocessing.connection import Clientclass TServer(ThreadingTCPServer):def __init__(self,server_add,ClientRequestHandler):ThreadingTCPServer.__init__(self, server_add, ClientRequestHandler)class ClientRequestHandler(StreamRequestHandler):def handle(self):Clientlist= []flag = Truewhile flag:clientadd =self.client_addressif clientadd in Clientlist:passelse:Clientlist.append(clientadd)self.wfile.write(b"hello")print(str(clientadd)+"已连接")if self.rfile.read(121):print(str(clientadd)+"已获取")passif __name__ == '__main__':address = ('',20025)server = TServer(address,ClientRequestHandler)server.serve_forever()pass

客户端的编写:

通过ADDR来规定套接字的元祖格式,通过connect的方法进行客户端的连接。在<<<<<<<<<<输入发送给服务器端的请求,最后使用close来关闭通信。

#coding:utf-8'''@author: 15006'''from _socket import socketfrom socket import *from test.test_gzip import data1from time import sleepHOST='localhost'PORT = 20025BUFSIZ = 1024ADDR = (HOST,PORT)tcpCliSock = socket(AF_INET,SOCK_STREAM)tcpCliSock.connect(ADDR)while True:data = input('>>>>>>>>> ')if not data:breaktcpCliSock.sendall(data.encode())data = tcpCliSock.recv(BUFSIZ)if not data:breakprint(data)sleep(20)tcpCliSock.close()if __name__ == '__main__':pass

代码效果:

依次运行服务器端文件和客户端文件:

显示IP与登录端口

在客户端输入121,收到回复hello,但是由于使用的是date.encode(),返回的是二进制流,所以显示的为b’hello’

最后服务器端读到121,显示已获得,完成一次完整的通信。

存在的问题:

1.客户端与服务器端只能建立一次通信

2.想要在代码中输入自定义的端口号,可是参考网上教程,需要编写解码器完成,多次尝试,没有成功

3.对于多线程与单线程的不太理解

4.不清楚这个代码中每次运行它显示的端口号都在改变,明明已经被定义在全局变量里了,为什么还会改变

编写过程中已经解决的问题:

1.服务器积极拒绝

原因是没有先开启服务器端,直接运行了客户端。

2.二进制流问题

由于使用的是date.encode(),返回的是二进制流,显示的为b’hello’,将date.encode()替换为data.encode(encoding='utf_8', errors='strict')即可解决

3.为什么服务器端重载方法为handle而不是setup

因为setup只能初始化,并不能对数据进行处理,handle中可以使用wfile和rfile来处理数据。

4.客户端一直尝试与服务器进行连接,可能导致服务器端崩溃

方法一:用sleep()设置间隔时间,简单但是面对大量数据请求会造成严重卡顿现象

方法二:每次请求过后close通信通道

基本流程梳理:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。