day26-socket(server和client通訊)

# socket是應用層與TCP/IP協議通訊的中間軟件抽象層,它是一組接口。它把複雜的TCP/IP協議隱藏到socket
#接口的後面,讓socket去組織數據,以符合指定的協議。
# socket是一個模塊,使用它來創建兩個程序之間的鏈接和通訊。也能夠把socket看作是ip+port,由於ip標識
#互聯網中一臺主機的位置,而port標識這臺主機上的一個應用程序,只要確立ip和port就能夠找到一個應用程序,
#而且使用socket模塊來與這個應用程序通訊。
# 先啓動server,等待client發信息。
#網絡傳輸的是bytes,recv接收以後,須要decode解碼。
#encode編碼,把str轉化爲bytes。

# 1、基於TCP的socket服務:
# 一、server服務端:
# 1.1
import socket
sk = socket.socket()         #買手機--建立套接字
# sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)避免服務重啓的時候報address already in use
sk.bind(('127.0.0.1',8080)) #綁定手機卡--綁定端口:sk.bind(('ip','port')),bind(元祖)
                                # 127.0.0.1是本機的迴環地址,用於本機內部應用程序的通訊。
sk.listen()             #監聽,等待有人給我打電話--偵聽客戶請求
conn,addr = sk.accept() #接收到別人的電話,--接受客戶端鏈接
                            # 獲得了鏈接conn(connection),和別人的地址addr(address)
#接收、發送--recv、send
ret = conn.recv(1024)    #聽別人說話,--接收客戶端信息
                            # 接收1024個字節,若是接收更長的信息能夠填寫2048或其餘更大的數字,recv(receive)接收
print(ret.decode('utf-8'))
conn.send(b'hi,client')  #和別人說話,必須傳一個bytes類型。--向客戶端發送信息。b'hi,client'至關於'hi,client'.encode('utf-8'))
ret = conn.recv(1024)
print(ret.decode('utf-8'))#接收的是bytes,要解碼爲utf-8
conn.send(bytes('你也不錯',encoding = 'utf-8')) #conn.send('你也不錯'.encode('utf-8'))

conn.close()        #掛電話--關閉客戶端套接字
sk.close()          #關手機--關閉服務器套接字

# 1.2 不停跟client聊天,直到說bye才結束。
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8082))
sk.listen()
conn,addr = sk.accept()

while True:
    ret = conn.recv(1024).decode('utf-8')
    if ret == 'bye':
        print(ret)
        conn.send(b'bye')
        break
    print(ret)
    info = input('>>>')
    conn.send(bytes(info,encoding = 'utf-8'))#conn.send(info.encode('utf-8'))

conn.close()
sk.close()


# 二、client客戶端:
# 2.1
import socket
sk = socket.socket()           #買手機
sk.connect(('127.0.0.1',8080))#撥號,鏈接別人的地址和端口

sk.send(b'hello,server')     #和別人說話
ret = sk.recv(1024)           #聽別人說話
print(ret.decode('utf-8'))
sk.send(bytes('你很好',encoding = 'utf-8'))
ret = sk.recv(1024)
print(ret.decode('utf-8'))

sk.close()                    #關手機

# 2.2 不停跟server聊天,直到說bye才結束。
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8082))

while True:
    info = input('>>>')
    sk.send(bytes(info,encoding = 'utf-8'))
    ret = sk.recv(1024).decode('utf-8')
    print(ret)
    if ret == 'bye':
        sk.send(b'bye')
        break
sk.close()

# 2、基於UDP的socket服務:不須要鏈接。
# 1.1 server服務端:
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',9000))

#沒有listen監聽和accept接收鏈接
ret,addr = sk.recvfrom(1024)  #接收client的addr是元祖,元祖沒有decode屬性,因此這裏不能寫sk.recvfrom(1024).decode('utf-8')
print(ret.decode('utf-8'))
sk.sendto(bytes('你好client',encoding='utf-8'),addr) #發送的時候須要填寫client的addr地址

sk.close()

# 1.2 client客戶端:
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
ip_port = ('127.0.0.1',9000) #server的地址和端口

sk.sendto(bytes('你好server',encoding='utf-8'),ip_port)#發送的時候須要把本身的地址一塊兒發給server
ret,addr = sk.recvfrom(1024)
print(ret.decode('utf-8'))

sk.close()

# 2.1 一個服務器端 對 兩個客戶端:例如qq聊天
#服務器端:
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',9000))
while True:
    ret,addr = sk.recvfrom(1024)
    print(ret.decode('utf-8'))
    info = input('>>>')
    sk.sendto(bytes(info,encoding='utf-8'),addr)
sk.close()

#客戶端1:
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
ip_port = ('127.0.0.1',9000)
while True:
    info = input('>>>')
    sk.sendto(bytes(('\033[31mclient1:%s\033[0m'%info).encode('utf-8')),ip_port)
    ret,addr = sk.recvfrom(1024)
    print(ret.decode('utf-8'))
sk.close()

#客戶端2:
import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
ip_port = ('127.0.0.1',9000)
while True:
    info = input('>>>')
    sk.sendto(bytes(('\033[31mclient2:%s\033[0m'%info).encode('utf-8')),ip_port)
    ret,addr = sk.recvfrom(1024)
    print(ret.decode('utf-8'))
sk.close()
相關文章
相關標籤/搜索