客户端与服务端

客户端/服务端大致分为两套,一套是TCP,一套是UDP。先看udp,tcp协议建立连接是要先发起链接的,而UDP没有链接,所以写的简单点。

下面是UDP的服务端:

 1 from socket import *
 2 
 3 ip_duan = ('127.0.0.1', 8000)
 4 buff = 1024
 5 
 6 udp_server = socket(AF_INET, SOCK_DGRAM)  # SOCK_STREAM是流式的套接字,sock_dgram是数据报式
 7 udp_server.bind(ip_duan)
 8 # 因为没有链接,所以没有listen,当然也就没有accept,直接进入通信循环
 9 
10 while True:
11     data, addr = udp_server.recvfrom(buff)      #recv是tcp,recvfrom是udp
12                                                # 返回的是一个元组,第一个是数据内容,第二个是客户端的IP+端口
13     print(data.decode('utf-8'))
14     udp_server.sendto(data.upper(),addr)
View Code

下面是UDP的客户端1与2(两个一样)

 1 from socket import *
 2 
 3 ip_duan = ('127.0.0.1', 8000)
 4 buff = 1024
 5 
 6 udp_client = socket(AF_INET, SOCK_DGRAM)  # SOCK_STREAM是流式的套接字,sock_dgram是数据报式
 7 # udp_client.bind(ip_duan)
 8 # 因为没有链接,所以没有listen,当然也就没有accept,直接进入通信循环
 9 
10 while True:
11     msg = input('===>')
12     udp_client.sendto(msg.encode('utf-8'),ip_duan)     # 没有链接,所以每次发的时候都要指定ip+duankou
13     print('客户端数据已经发送')
14     data, addr = udp_client.recvfrom(buff)
15     print(data.decode('utf-8'))
View Code

先大致说一下TCP与UDP区别:

UDP不用建立链接,所以服务器不用listen,accept,客户端发是sendto(发时代ip+ipot),收是recvfrom。

TCP不可以发空(空不是空格,是直接回车),所以发东西后要判断非空;但是udp从表面上看可以。

TCP服务端同一时刻只能服务一个客户端,第二个链接先挂起,等第一个客户端通讯(聊天)退出才到第二个通讯;UDP由于没有链接可以轻松实现并发。

TCP可能有粘包现象(无论TCP与UDP的发送还是接收,他们都是先到自己的缓存区,由于不知道收多少字节,可能会没收完,下次放一起),UDP永远不会有。

下面是说TCP,如下是TCP的服务端:

 1 from socket import *
 2 
 3 ip_duan = ('127.0.0.2', 8000)
 4 back_log = 5          # 缓存池大小
 5 buff = 1024            # 接收缓存大小字节
 6 
 7 tcp_server = socket(AF_INET, SOCK_STREAM)
 8 tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)    #当出现address already in use 错误时,可以加这条避免
 9 tcp_server.bind(ip_duan)
10 tcp_server.listen(back_log)
11 
12 print('服务器正在执行===============》')
13 
14 while True:     # 循环可以接受多个链接,也就是说不只是为一个客户端服务
15     conn, address = tcp_server.accept()
16     print('双向连接',conn)
17     print('新的客户端链接',address)
18 
19     while True:      # 这个循环是可以多次通话
20         try:          # 加try except是为了当一个客户端端口时,不至于因为没有conn而报错
21             msg = conn.recv(buff)
22             if not msg:
23                 break            # 解决死循环
24             print('服务器收到来自客户端的信息是: ',msg.decode('utf-8'))
25             conn.send(msg.upper())
26         except Exception:
27             break
28 
29     conn.close()
30 
31 tcp_server.close()
View Code

如下是TCP的客户端1与2:

 1 from socket import *
 2 
 3 ip_duan = ('127.0.0.2', 8000)
 4 buff = 1024
 5 
 6 tcp_client = socket(AF_INET, SOCK_STREAM)
 7 tcp_client.connect(ip_duan)
 8 
 9 while True:
10     msg = input('==>')
11     if not msg:
12         continue
13     tcp_client.send(msg.encode('utf-8'))
14     print('客户端消息已经发送')
15     data = tcp_client.recv(buff)
16     print('客户端收到来自服务器的消息是:',data.decode('utf-8'))
17 
18 tcp_client.close()
View Code

简单点评,上面写得TCP的c/s还有很多问题没有解决,比如最明显的是,客户端1连接后,客户端2虽然也可以连接发送消息,但是客户端2接收消息要等客户端1断开后才可以接收它的消息。

猜你喜欢

转载自www.cnblogs.com/maxiaonong/p/9498351.html