python socket能做什么_用python写一个聊天小程序!和女朋友的专属聊天工具!
原標(biāo)題:用python寫一個(gè)聊天小程序!和女朋友的專屬聊天工具!
1.UDP簡(jiǎn)介
Internet協(xié)議集支持一個(gè)無(wú)連接的傳輸協(xié)議,該協(xié)議稱為用戶數(shù)據(jù)報(bào)協(xié)議(UDP)。UDP為應(yīng)用程序提供了無(wú)需建立就可以發(fā)送封裝的IP數(shù)據(jù)包的方法。
Internet的傳輸層有兩個(gè)協(xié)議,互為補(bǔ)充。無(wú)連接是UDP,它除了給應(yīng)用程序發(fā)送數(shù)據(jù)包功能并允許他們所需的層次上架構(gòu)自己的協(xié)議之外,幾乎沒有做什么特別的事情。面向連接的是TCP,該協(xié)議幾乎做了所有的事情。
中文名:用戶數(shù)據(jù)協(xié)議
外文名:User Datagram Protocol
特點(diǎn):無(wú)連接、不可靠、快速傳輸
基礎(chǔ):IP數(shù)據(jù)包服務(wù)上增加一點(diǎn)功能
類別:傳輸層協(xié)議
用途:發(fā)送數(shù)據(jù)包
2.socket
一般socket我們稱為套接字,并且在Python中有socket這個(gè)庫(kù)(可以使用pip命令自行下載pip install socket)。下面來(lái)說(shuō)一下socket的簡(jiǎn)單流程:
1. 獲取套接字
2. 綁定端口
3. 選擇發(fā)送或者接受
4. 關(guān)閉套接字
2-1 socket的發(fā)送
socket的發(fā)送很簡(jiǎn)單,下面是一般的最簡(jiǎn)代碼:
# -*- coding: utf-8 -*-
import socket
def sendMsg():
# 獲取套接字
send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 為套接字綁定端口與ip
# 這里的""是表示當(dāng)前綁定的ip為本機(jī)的ip,后面的數(shù)字為該程序所綁定的端口號(hào)。
# 如果不提前綁定端口號(hào),則可能發(fā)送的時(shí)候,有電腦自動(dòng)為該程序分發(fā)一個(gè)端口號(hào)。
send_socket.bind(("", 7879)) # 當(dāng)然這個(gè)端口也可以是7878,即發(fā)送的端口,后續(xù)會(huì)繼續(xù)講解
# 設(shè)置發(fā)送
send_socket.sendto(b"123", ("127.0.0.1", 7878))
# 關(guān)閉套接字
send_socket.close()
if __name__ == '__main__':
sendMsg()
2-2 socket的接收
注意,在recv中,一定需要提前綁定端口,因?yàn)檫@是接收消息的前提條件,那么選用什么端口呢?一般做實(shí)驗(yàn)或者寫程序的時(shí)候,我們可以選擇的端口范圍在[1024-65535]之間。因?yàn)樯厦嬉呀?jīng)創(chuàng)建了socket的發(fā)送,并且選定了端口號(hào)為7878,那么我們此時(shí)的端口只需要綁定7878即可。
recv_socket.recvfrom(1024)表示單次接受的最大字節(jié)為1024,如果超出這個(gè)數(shù)值,那么只取前面的1024個(gè)。并且該函數(shù)返回的值是一個(gè)元組,與socket發(fā)送時(shí)一致(b"123", ("127.0.0.1", 7878)),因此在想要獲取接受的內(nèi)容是,需要利用下標(biāo)索引。這里還需要注意一點(diǎn),因?yàn)槲覀冊(cè)趥鬏數(shù)臅r(shí)候是靠字節(jié)去傳輸?shù)?#xff0c;因此獲取到的也是字節(jié),我們需要為它進(jìn)行編碼,但是win系統(tǒng)與linux系統(tǒng)是不相同的,win系統(tǒng)默認(rèn)的是gbk編碼,但是linux默認(rèn)的是utf-8編碼,因此在獲取字節(jié)之后,需要根據(jù)系統(tǒng)的類型選擇相應(yīng)的解碼格式。
# -*- coding: utf-8 -*-
import socket
def recvMsg():
# 創(chuàng)建套接字
recv_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口
recv_socket.bind(("", 7878))
# 接收字節(jié)
recv_data = recv_socket.recvfrom(1024) # 這里的數(shù)字表示單次接受的最大字節(jié)數(shù)
# 轉(zhuǎn)化打印出內(nèi)容
print("接收到來(lái)自{},的{}信息".format(recv_data[1],recv_data[0].decode("gbk")))
# 關(guān)閉套接字
recv_socket.close()
if __name__ == '__main__':
recvMsg()
3.實(shí)現(xiàn)收發(fā)功能
我們需要提前了解一些知識(shí)點(diǎn):單工:只能收或者發(fā)、半雙工:可以收也可以發(fā),但是不能同時(shí)運(yùn)行、全雙工:同一時(shí)刻既可以收也可以發(fā)。并且socket是支持同時(shí)接收與發(fā)送數(shù)據(jù)的,因此socket是全雙工的。
下面代碼是實(shí)現(xiàn)socket的發(fā)送與接收功能
# -*- coding: utf-8 -*-
import socket
def SendAndRecv():
"""
套接字是可以同時(shí)收發(fā)數(shù)據(jù)的
單工:只能收或者發(fā)
半雙工:可以收也可以發(fā),但是不能同時(shí)運(yùn)行
全雙工:同一時(shí)刻既可以收也可以發(fā)
注意:socket是全雙工
"""
# 獲取套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口(也可以不綁定,只需要查看發(fā)送時(shí)的端口號(hào),在重新輸入即可,但是這個(gè)程序最好提前綁定端口
udp_socket.bind(("", 7789))
# 發(fā)送對(duì)方信息
udp_socket.sendto(b"hahahah", ("127.0.0.1", 7788))
# 接收對(duì)方返回的信息,如果沒有收到字符,則會(huì)阻塞,直到有信息返回
recv_data = udp_socket.recvfrom(1024)
# 轉(zhuǎn)化打印出內(nèi)容
print("接收到來(lái)自{},的{}信息".format(recv_data[1], recv_data[0].decode("gbk")))
# 關(guān)閉套接字
udp_socket.close()
if __name__ == '__main__':
SendAndRecv()
上面代碼的確看起來(lái)有點(diǎn)“丑陋”我們來(lái)給他進(jìn)行一些封裝
# -*- coding: utf-8 -*-
import socket
def send_msg(udp_socket):
"""發(fā)送消息"""
udp_socket.sendto(b'124124', ("127.0.0.1", 7788))
def recv_msg(udp_socket):
"""接收數(shù)據(jù)"""
recv_data = udp_socket.recvfrom(1024)
print("%s:%s" % (str(recv_data[1]), recv_data[0].decode("gbk"))) # 如果是win系統(tǒng)通信,需要把deckde的解碼格式改為gbk,但是在linux中可以為utf-8
def main():
# 創(chuàng)建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口
udp_socket.bind(("", 7789))
# 循環(huán)來(lái)處理事情
while True:
print("------DreamsPy聊天器------")
print("1:發(fā)送消息")
print("2:接收消息")
print("0:退出系統(tǒng)")
op = input("請(qǐng)輸入功能:")
if op == "1":
# 發(fā)送
send_msg(udp_socket)
elif op == "2":
# 接收數(shù)據(jù)并顯示
recv_msg(udp_socket)
elif op == "0":
break
else:
print("您輸入的命令有誤,請(qǐng)重新輸入")
if __name__ == '__main__':
main()
以上代碼實(shí)現(xiàn)了程序的接受和發(fā)送。但是我們需要寫兩個(gè)程序來(lái)驗(yàn)證是否能執(zhí)行吧,以下兩個(gè)就是發(fā)送的檢測(cè)代碼和接收的檢測(cè)代碼。
# -*- coding: utf-8 -*-
import socket
def recvMsg():
# 創(chuàng)建套接字
recv_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 綁定端口
recv_socket.bind(("", 7788))
# 接收字節(jié)
recv_data = recv_socket.recvfrom(1024) # 這里的數(shù)字表示單次接受的最大字節(jié)數(shù)
# 轉(zhuǎn)化打印出內(nèi)容
print("接收到來(lái)自{},的{}信息".format(recv_data[1],recv_data[0].decode("gbk")))
# 關(guān)閉套接字
recv_socket.close()
if __name__ == '__main__':
recvMsg()
上面的代碼是主程序接收是否能實(shí)現(xiàn)。
# -*- coding: utf-8 -*-
import socket
def sendMsg():
# 獲取套接字
send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 設(shè)置發(fā)送
send_socket.sendto(b"123", ("127.0.0.1", 7789))
# 關(guān)閉套接字
send_socket.close()
if __name__ == '__main__':
sendMsg()
上面的代碼是主程序發(fā)送是否能實(shí)現(xiàn)。
當(dāng)然為了嚴(yán)謹(jǐn),同樣可以在main函數(shù)里加上while True進(jìn)行無(wú)限循環(huán)來(lái)驗(yàn)證,并且可以用戶手動(dòng)輸入需要發(fā)送的ip地址、端口號(hào)、發(fā)送內(nèi)容。這里就不一一寫出來(lái)了,剩下的就留給大家了。
以上就是python利用socket寫的聊天小程序。思路比較簡(jiǎn)單,代碼也比較容易上手。tcp也是重點(diǎn)(后續(xù)會(huì)發(fā)),多多復(fù)習(xí)多多練習(xí)喲。返回搜狐,查看更多
責(zé)任編輯:
總結(jié)
以上是生活随笔為你收集整理的python socket能做什么_用python写一个聊天小程序!和女朋友的专属聊天工具!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python oracle数据库开发_p
- 下一篇: 拍卖源码java_Java并发的AQS原