socket編程補充

  • 2019 年 10 月 6 日
  • 筆記

tcp伺服器

udp不區分伺服器和客戶端的。

在常用模組中我們學習了socket的模組,

並且模擬實現了udp和tcp的客戶端,我們知道想要通訊必須是客戶端與伺服器連接才能通訊,

下面我們來模擬實現tcp的伺服器。

實現流程:

1、socket 創建一個套接字

2、bind綁定ip和port

3、listen使套接字變為被動鏈接(監聽套接字)

4、accept等待客戶端鏈接

5、recv/send接收和發送數據

6、關閉套接字

import socket

def main():

# 創建套接字

tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# 綁定本地資訊

tcp_server.bind(("",7890))

# 將套接字變為被動

tcp_server.listen(128)

# 等待客戶端的連接

print('等待')

cli_socket,cli_addr = tcp_server.accept()

# accept()返回一個元組,第一個值接收一個新的套接字,第二個接收連接客戶端的地址。

# recv/send接收和發送數據

# cli_socket這個套接字接收消息。

recv_data = cli_socket.recv(1024)

cli_socket.send('ok'.encode('utf-8'))

#關閉套接字

cli_socket.close()

tcp_server.close()

if __name__ == "__main__":

main()

修改一下:

修改成等待多個客戶端,並對一個客戶端多次服務。

import socket

def main():

# 創建套接字

tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# 綁定本地資訊

tcp_server.bind(("",7890))

# 將套接字變為被動

tcp_server.listen(128)

#128 和作業系統有關,比如一個網站同時有128個人訪問。那我們寫1000000呢?是不是更多?不是這樣

暫時默認寫128就行了。

# 等待客戶端的連接

while True:

print('等待')

cli_socket,cli_addr = tcp_server.accept()

# accept()返回一個元組,第一個值接收一個新的套接字,第二個接收連接客戶端的地址。

while True:

# recv/send接收和發送數據

# cli_socket這個套接字接收消息。

# 這裡需要判斷對方是否關閉,關閉即服務完畢

recv_data = cli_socket.recv(1024)

# 當recv_data為空,就表示結束服務。

if not recv_data:

cli_socket.send('ok'.encode('utf-8'))

else:

break

#關閉套接字

cli_socket.close()

tcp_server.close()

if __name__ == "__main__":

main()

tcp下載文件

# tcp下載文件客戶端

from socket import *

def main():

# 創建套接字

tcp_socket = socket(AF_INET,SOCK_STREAM)

# 輸入ip和port

ip = input('輸入伺服器ip')

port = int(input('輸入伺服器port'))

# 連接伺服器

tcp_socket.connect((ip,port))

# 輸入需要下載的文件名

file_name = input('要下載的文件名')

# 發送下載請求

tcp_socket.send(file_name.encode('utf-8'))

# 接收伺服器發來的數據1024 = 1k

recv_data = tcp_socket.recv(1024)

# 收到數據創建文件夾,寫入數據

if recv_data:

with open("xxx"+file_name,"wb") as file:

file.write(recv_data)

# 關閉套接字

tcp_socket.close()

if __name__ == "__main__":

main()

# tcp下載文件服務端

import socket

def main():

tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

tcp_server.bind(("",7891))

tcp_server.listen(128)

cli_socket,cli_addr = tcp_server.accept()

# cli_socket這個套接字接收文件名字。

recv_data = cli_socket.recv(1024).decode('utf-8')

# 發送文件消息

cli_socket.send('我是文件的內容'.encode('utf-8'))

#關閉套接字

cli_socket.close()

tcp_server.close()

if __name__ == "__main__":

main()

其他:

我們在發數據的時候需要一個固定的埠,在接收數據的時候,只要知道對方伺服器的埠就可以了。

也就是說,tcp客戶端一般不綁定埠,如果綁定不及存在多開了!