<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## **一 最簡單的C/S實現** 基于前面的打電話偽代碼,實現服務器與客戶端的單次通信 **server端代碼** ``` import socket #1、買手機 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #2、綁定手機卡 phone.bind(('127.0.0.1',8081)) #元組形式的主機和端口 #3、開機 phone.listen(5) #允許5個連接排隊 #4、等電話鏈接 print('starting...') conn,client_addr=phone.accept() #接受的數據是一個元組 #5、收,發消息 data=conn.recv(1024) #1024代表最大接收1024個bytes print('客戶端的數據',data.decode('utf-8')) #接受的是bytes,需要轉碼 conn.send(data.upper()) #6、掛電話 conn.close() #7、關機 phone.close() ``` **client端代碼** ``` import socket #1、買手機 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #2、撥號 phone.connect(('127.0.0.1',8081)) #3、發,收消息 phone.send('hello'.encode('utf-8')) #只能發送bytes類型,所以要轉碼 data=phone.recv(1024) print(data.decode('utf-8')) #4、關閉 phone.close() ``` ## **二 循環發送消息的實現** 上面的代碼客戶端和服務器斷只能通信一次,然后就會斷開連接,如果想多次發送數據,就需要加入循環語句 **server端代碼** ``` import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.bind(('127.0.0.1',8083)) phone.listen(5) print('starting...') conn,client_addr=phone.accept() while True: #通信循環 data=conn.recv(1024) print('客戶端的數據',data) conn.send(data.upper()) conn.close() phone.close() ``` **client端代碼** ``` import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.connect(('127.0.0.1',8083)) while True: #通信循環 msg=input('>>: ').strip() if not data:continue #避免發送空數據 phone.send(msg.encode('utf-8')) data=phone.recv(1024) print(data) phone.close() ``` ### **bug解釋和修復** 上面的代碼有2個bug,關于bug的說明和修改方式如下 1. client直接斷開服務的話,server端會報錯 修改server端的通信循環為如下樣式,分別針對linux和windows服務器做不同的處理 ``` while True: #通信循環 try: data=conn.recv(1024) if not data:break #適用于linux操作系統 print('客戶端的數據',data) conn.send(data.upper()) except ConnectionResetError: #適用于windows操作系統 break ``` 2. 重啟server端時可能提示端口占用 問題是由于服務端仍然存在四次揮手的time_wait狀態在占用地址 解決方法1:socket方法 ~~~ sock_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #寫在bind前 sock_server.bind((HOST, PORT)) ~~~ 解決方法2:linux內核辦法 `vi /etc/sysctl.conf`,在打開文件中加入以下內容: net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 30 然后執行 `/sbin/sysctl -p `讓參數生效。 >net.ipv4.tcp_syncookies = 1 表示開啟SYN Cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防范少量SYN攻擊,默認為0,表示關閉; net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用于新的TCP連接,默認為0,表示關閉; net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。 net.ipv4.tcp_fin_timeout 修改系統默認的 TIMEOUT 時間 ## **循環建立連接的實現** 上面的C/S結構代碼,僅能支持client與server一對一的通信,如果client斷開連接也不會有新的客戶端被接入,因此需要server段再建立連接處再加一層循環實現循環建立連接 **server端代碼** ``` import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) phone.bind(('127.0.0.1',8083)) #0-65535:0-1024給操作系統使用 phone.listen(5) print('starting...') while True: # 鏈接循環 conn,client_addr=phone.accept() print(client_addr) while True: #通信循環 try: data=conn.recv(1024) if not data:break #適用于linux操作系統 print('客戶端的數據',data) conn.send(data.upper()) except ConnectionResetError: #適用于windows操作系統 break conn.close() phone.close() ``` client端代碼不需要任何改變 ### **特別說明** 如上修改后,能實現多個客戶端排隊連接客戶端進行通話的情況,但是實現不了多個客戶端同時連接服務端通話的情況,需要用到后面的**并發編程**知識
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看