一、实验目的:
掌握应用层网络通信程序编制的方法。
二、实验内容:
1、学习和熟悉网络编程函数
2、基于客户/服务器模型,编制网络通信程序
三、实验要求:
分别编制客户程序和服务器程序。其基本功能要求是:
启动运行后,客户端进程发送一个字符串(例如I LOVE CUGB),服务器接收到后,进行反转显示(如:BGUC EVOL I)。
提示:如果只有一台计算机也可以实现本实验,需要把目的IP地址设置成127.0.0.1
四、实验步骤:
本次实验我使用Python语言来进行,使用的编译器是Visual Studio Code。
首先进行Server服务器端的编程,文件为server.py,在文件首部需要socket库和sys库,分别作用于socket编程和退出。在本程序里面用了许多try语句的异常处理的用法,当发生错误的时候就会抛出错误并且退出程序。
在最开始我们需要创建套接字,上述代码使用了下面两个属性来创建 Socket:
地址簇 : AF_INET (IPv4)
类型: SOCK_STREAM (使用 TCP 传输控制协议)
就这样建立套接字socket之后放入s中,若发生错误则会抛出提示并且退出,反之则会显示“套接字创建成功!”。
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error as msg:
print ('无法创建套接字Socket')
sys.exit();
print ('套接字创建成功!')
然后我们需要得到本机的IP地址,可以使用终端输入”ipconfig”得到本机IPv4地址:172.20.55.148,也可以使用Socket库中函数gethostbyname(),同样也抛出错误,若无法解析则提示并退出,否则就存入host,并且设置端口号port为8088,可修改。
try:
#host = '172.20.55.148'
host = socket.gethostbyname(socket.gethostname())
except socket.gaierror:
print('主机名无法解析...')
sys.exit()
port = 8088
print('IP地址:',host,'端口:',port)
然后就是进行bind绑定,对Socket绑定到我所用的IP地址和端口号,同样若失败则抛出错误,否则显示绑定成功。bind()函数需要之前设置的host和port变量即可。
#s.bind((host, port))
try:
s.bind((host, port))
except socket.error :
print ('绑定发生错误')
sys.exit()
print('套接字绑定成功!')
绑定之后则需要进行侦听,需要将Socket变成侦听模式,用到socket()函数,里面放入一个参数,我设置的是s.listen(5),代表可保持等待状态的连接数,这里表示最多有5个连接等待处理,若此时来了第6个则会拒绝。
s.listen(5)
print('正在侦听...')
到这个地步就差不多完成了,接下来就是等待客户端的连接,这边只需要接受连接即可,我这里设置的是while循环一直进行,也就是客户端可以不断连接断开,服务器端一直打开接受连接。
在这个while循环里面,对于每一次连接进行一系列处理。socket内的accept函数即可完成接受连接,并且显示连接到对方的地址。
c,address = s.accept()
print('连接到地址:',address[0],':',address[1],sep='')
然后就可以收到客户端发送的信息,如果对方发送的是”exit”的话则退出接收信息,输出“连接断开”并关闭连接,进行下一次的等待接受连接,用到socket中的close()函数。如果不是”exit”的话,则将话原封不动的发送回去,通知客户端收到的是正常的,具体操作请见客户端,然后进行实验要求的倒置字符的功能,并且显示,这样这一次的接收信息并倒置显示也就到此结束,然后进行下一次的接收信息的处理,如此循环,直到接收到”exit”,这里收到信息用到socket中recv()的函数,参数是对其进行长度的控制。
while True:
str = c.recv(1024).decode()
if str == 'exit':
break
send(str)
str = reverse(str)
print(str)
print('连接断开')
c.close()
上面用到了发送信息的函数send()以及reverse()函数,分析如下:
send()函数:
同样也是try语句,如果发送失败了则会抛出“发送失败”的提示,如果成功则用到socket库中send()函数,注意这里则需要用到对str进行encode编码,同样,当接收到信息的时候也需要decode解码。
def send(str):
try :
#str = 'I LOVE CUGB'
c.send(str.encode('utf-8'))
except socket.error:
print(str,'发送失败')
sys.exit()
reverse()函数:
这里用循环逆序遍历得到新字符串并返回
def reverse(st):
res = ''
for i in range(len(st) - 1, -1, -1):
res += st[i]
return res
(实际上可以用函数,我为了多写一点就...)
至此,服务器端程序步骤全部结束。然后是客户端的步骤,在文件开头同样需要socket和sys库,分别用于socket编程和退出程序。
首先也同样需要创建套接字Socket放入s中,同服务器端的代码,同样若发生错误也会抛出错误。
然后需要设置host和port两个变量,也就是IP地址以及端口号,用于之后的connect连接。
host = '172.20.55.148'
port = 8088
然后使用socket里面的connect()函数,需要之前的host和port两个变量进行连接,这时候对应的是服务器端侦听中的accept()函数。
s.connect(( host , port ))
print('连接到IP地址为:',host,'端口为:',port)
到这里,二者已经连接上了,服务器端此时等待客户端的发送的信息,而客户端现在就是需要发送信息。我们对实验要求的”I LOVE CUGB”进行测试,进行发送,这里的send()函数也是同客户端定义的函数。
str = 'I LOVE CUGB'
send(str)
然后对服务器端返回的信息进行判断,因为服务器端是返回所收到的,所以客户端也就是得到的是服务器端收到的,如果二者不相同则发生了错误,显示提示。收到消息则也用到socket中的recv()函数,发送端进行encode()编码,则接收端需要decode()解码。
st = s.recv(1024).decode()
if st == str :
print('接收成功! 服务器端成功接收到了消息:',st)
else:
print('接收失败! 服务器端没有收到消息:',st)
到此实验的基本要求已经结束,正常的话在服务器端则会收到然后进行倒置输出。接下来是实现了可以一直对服务器端进行发送消息,同上的”I LOVE CUGB”,如果遇到”exit”则会通知服务器端,然后进行退出,退出则用到socket中的close()函数。
while True:
str = input()
send(str)
if str == 'exit':
print('退出连接')
break
st = s.recv(1024).decode()
if st == str :
print('发送成功! 服务器端成功接收到了消息:',st)
else:
print('发送失败! 服务器端没有收到消息:',st)
s.close()
至此,程序退出,若有需要可以重新进行运行,重新连接。
五、实验结果
首先需要服务器端(server.py)进行运行,若一切正常则会按照步骤显示一系列提示,如下:
然后运行客户端(client.py),对服务器端进行连接,客户端显示:
则实现了”I LOVE CUGB”的倒置显示,因为我的功能是可以一直发送消息的,直到客户端输入”exit”结束,结果如下:
正如结果所示,如果客户端发送的消息与服务器端收到的消息一致,则显示“发送成功!”,而服务器端则会进行倒置显示。
文章评论