{"id":547,"date":"2020-04-03T18:33:57","date_gmt":"2020-04-03T10:33:57","guid":{"rendered":"https:\/\/www.caiqinyi.cn\/?p=547"},"modified":"2025-02-26T11:35:16","modified_gmt":"2025-02-26T03:35:16","slug":"socket_chatroom","status":"publish","type":"post","link":"https:\/\/www.caiqinyi.cn\/index.php\/2020\/04\/03\/socket_chatroom\/","title":{"rendered":"\u4f7f\u7528Python\u4e2d\u7684Socket\u7f16\u7a0b\u5b9e\u73b0Unity\u7684\u804a\u5929\u5ba4\u529f\u80fd"},"content":{"rendered":"<p>\u6700\u8fd1\u5f00\u59cb\u4f7f\u7528Python\u4e2d\u7684Socket\u7f16\u7a0b\u7740\u624b\u5b9e\u73b0Unity\u7684\u804a\u5929\u5ba4\u529f\u80fd, \u4f46\u4e4b\u524d\u81ea\u5df1\u7684\u670d\u52a1\u7aef\u7f16\u7a0b\u7ecf\u9a8c\u57fa\u672c\u4e3a0(\u867d\u7136\u4e4b\u524d\u4f7f\u7528\u8fc7Unity\u7684Network\u63d2\u4ef6, \u4f46\u8be5\u63d2\u4ef6\u4ec5\u9002\u7528\u4e8e\u5c40\u57df\u7f51, \u4e14\u4f7f\u7528\u8fc7\u7a0b\u4e2d\u8fd8\u662f\u5b58\u5728\u7740\u8f83\u591a\u7684bug), \u6240\u4ee5\u8fd8\u662f\u8d70\u5f97\u6bd4\u8f83\u574e\u5777~<\/p>\n<p><!--more--><\/p>\n<p><strong>\u53c2\u8003\u6750\u6599<\/strong><br \/>\n1. <a href=\"https:\/\/swf.com.tw\/?p=1198\">Python\u7684\u975e\u963b\u585e\u5f0f\uff08non-blocking\uff09socket\u901a\u8a0a\u7a0b\u5f0f<\/a><br \/>\n2. <a href=\"https:\/\/blog.csdn.net\/Shenpibaipao\/article\/details\/70236657\">[JAVA]Socket\u4e2dBufferedReader.readLine()\u7684\u963b\u585e\u7279\u6027\u5bfc\u81f4\u7684\u6570\u636e\u65e0\u6cd5\u591a\u6b21\u53d1\u9001\u7684\u95ee\u9898<\/a><br \/>\n3. <a href=\"https:\/\/blog.csdn.net\/jing16337305\/article\/details\/79856116\">Python\u4e2dsend()\u548csendall()\u7684\u533a\u522b<\/a><\/p>\n<p>\u76ee\u524d\u7684\u4e3b\u8981\u5de5\u4f5c\u90fd\u96c6\u4e2d\u5728\u670d\u52a1\u7aef\u642d\u5efa\u4e0a, \u6838\u5fc3\u4ee3\u7801\u4e3a<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"Python\" data-enlighter-theme=\"monokai\">\r\n#!\/usr\/bin\/env python\r\n# -*- coding: UTF-8 -*-\r\n\r\nimport socket\r\nimport string\r\nfrom client import Client\r\n\r\nclass Server:\r\n    clientList = []\r\n\r\n    def broadcastMessage(self, message):\r\n        '''\r\n        \u5e7f\u64ad\u6d88\u606f\r\n        @param message: \u5f85\u5e7f\u64ad\u7684\u6d88\u606f\r\n        @return: void\r\n        '''\r\n        for client in self.clientList:\r\n            if client != None and client.isConnected:\r\n                client.sendMessage(message)\r\n\r\n    def main(self, host, port, backlog, size):\r\n        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n        s.bind((host, port))\r\n        s.setblocking(False)\r\n        s.settimeout(0.5)\r\n        s.listen(backlog)\r\n        print \"Server running on port \" + str(port)\r\n\r\n        while True:\r\n            try:\r\n                client, address = s.accept()\r\n                print 'Client ' + str(len(self.clientList) + 1) + ' connects.\\n'\r\n                client.sendall('\u6b22\u8fce\u4f60, \u73a9\u5bb6' + str(len(self.clientList) + 1) + '!\\n')\r\n                self.clientList.append(Client(client, size))\r\n            except:\r\n                pass\r\n\r\n            for client in self.clientList:\r\n                if client != None:\r\n                    if client.isConnected:\r\n                        if client.isSend:\r\n                            self.broadcastMessage(client.data)\r\n                    else:\r\n                        index = self.clientList.index(client)\r\n                        self.clientList[index] = None\r\n                        print 'Client ' + str(index + 1) + ' goes away.\\n'\r\n<\/pre>\n<p>\u5176\u4e2d\u4f7f\u7528\u7684Client\u7c7b\u7684\u5b9a\u4e49\u4e3a<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"Python\" data-enlighter-theme=\"monokai\">\r\n#!\/usr\/bin\/env python\r\n# -*- coding: UTF-8 -*-\r\n\r\nimport socket\r\nimport string\r\nimport threading\r\n\r\nclass Client:\r\n    client = None\r\n    isConnected = True\r\n    isSend = False\r\n    data = ''\r\n\r\n    def __init__(self, s, size):\r\n        self.client = s\r\n        self.client.setblocking(False)\r\n        self.client.settimeout(0.5)\r\n        self.isConnected = True\r\n        t = threading.Thread(target = self.receiveMessage, args = [size])\r\n        t.start()\r\n\r\n    def receiveMessage(self, size):\r\n        while True:\r\n            if not self.isConnected:\r\n                break\r\n            try:\r\n                # \u63a5\u6536\u6d88\u606f\r\n                self.data = self.recv(size).rstrip('\\r\\n')\r\n                if self.data == b\"\":\r\n                    self.isConnected = False\r\n                    self.isSend = False\r\n                    break\r\n                else:\r\n                    self.sendMessage('\u4f60\u521a\u521a\u8bf4: ' + self.data)\r\n                    # \u5e7f\u64ad\u6d88\u606f\r\n                    self.isSend = True\r\n            except:\r\n                self.isSend = False\r\n        self.close()\r\n\r\n    def sendMessage(self, message):\r\n        self.client.sendall(message + '\\n')\r\n\r\n    def recv(self, size):\r\n        return self.client.recv(size)\r\n\r\n    def getsockname(self):\r\n        return self.client.getsockname()\r\n\r\n    def close(self):\r\n        self.client.close()\r\n<\/pre>\n<p>\u5176\u4e2d, \u503c\u5f97\u6ce8\u610f\u7684\u6709\u4ee5\u4e0b\u51e0\u70b9.<\/p>\n<p>1. \u9488\u5bf9\u591a\u5ba2\u6237\u7aef\u60c5\u5f62\u9700\u8981\u4f5c\u5982\u4e0b\u8bbe\u7f6e,<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"Python\" data-enlighter-theme=\"monokai\">\r\ns.setblocking(False)\r\ns.settimeout(0.5)\r\n<\/pre>\n<p>\u901a\u8fc7setblocking\u65b9\u6cd5\u5c06\u670d\u52a1\u7aefsocket\u8bbe\u7f6e\u4e3a\u975e\u963b\u585e\u6a21\u5f0f, \u540c\u65f6\u8bbe\u7f6e\u8d85\u65f6\u65f6\u95f4\u4e3a0.5\u79d2, \u5bf9\u4e8e\u8fd9\u4e2a\u8d85\u65f6\u65f6\u95f4\u6211\u7684\u7b80\u5355\u7406\u89e3\u4e3a\u6bcf\u96940.5\u79d2\u6267\u884c\u4e00\u6b21while\u5faa\u73af\u4e2d\u7684\u4ee3\u7801, \u800c\u975e\u4e4b\u524d\u7684\u6bcf\u4e00\u5e27\u90fd\u5728\u6267\u884c, \u90a3\u6837\u6211\u89c9\u5f97\u662f\u6bd4\u8f83\u6d88\u8017\u8ba1\u7b97\u673a\u6027\u80fd\u7684.<\/p>\n<p>2. \u5f53\u4ec5\u662f\u4f5c\u51fa\u4e861\u4e2d\u7684\u6539\u52a8, \u800c\u6ca1\u6709\u8fdb\u884c\u540e\u7eed\u5904\u7406\u7684\u8bdd, \u5bb9\u6613\u51fa\u73b0BlockingIOError(\u963b\u585eIO\u9519\u8bef), \u8fd9\u662f\u56e0\u4e3a\u7a0b\u5e8f\u539f\u672c\u5e94\u8be5\u505c\u5728s.accept()\u90a3\u4e00\u884c, \u7b49\u5230\u6709\u5ba2\u6237\u7aef\u8fde\u7ebf\u518d\u81ea\u52a8\u7ee7\u7eed\u6267\u884c\u540e\u9762\u7684\u4ee3\u7801, \u7531\u4e8e\u670d\u52a1\u7aefsocket\u88ab\u8bbe\u5b9a\u6210\u4ee5\u975e\u963b\u585e\u65b9\u5f0f\u6267\u884c, \u5bfc\u81f4\u7a0b\u5e8f\u6c92\u6709\u505c\u6b62. \u5728\u6c92\u6709\u5ba2\u6237\u7aef\u8fde\u7ebf\u7684\u60c5\u6cc1\u4e0b, \u5f3a\u5236\u6267\u884caccept(), \u5c31\u6703\u51fa\u73feBlockingIOError.<\/p>\n<p>\u89e3\u51b3\u7684\u65b9\u6cd5\u662f\u7528try\u2026except\u5305\u88c5\u53ef\u80fd\u4f1a\u51fa\u9519\u7684\u53d9\u8ff0. \u5ba2\u6237\u7aefsocket\u7684recv(\u63a5\u6536\u6d88\u606f)\u65b9\u6cd5\u4e5f\u6703\u9020\u6210\u963b\u585e, \u5f53\u5ba2\u6237\u7aefsocket\u6539\u6210\u975e\u963b\u585e\u65b9\u5f0f\u4e4b\u5f8c, \u5728\u5c1a\u672a\u6536\u5230\u5ba2\u6237\u7aefsocket\u7684\u6d88\u606f\u65f6\u5f3a\u5236\u6267\u884crecv\u5c06\u9020\u6210\u9519\u8bef, \u56e0\u6b64\u4e5f\u8981\u7528try\u2026except\u5305\u88dd.<\/p>\n<p>3. threading.Thread\u65b9\u6cd5\u521b\u5efa\u4e00\u4e2a\u65b0\u7ebf\u7a0b\u7528\u4e8e\u76d1\u542c\u5ba2\u6237\u7aefsocket\u7684\u6d88\u606f, \u9700\u8981\u6ce8\u610f\u7684\u662f, \u5c3d\u91cf\u4e0d\u8981\u5728\u591a\u4e2a\u7ebf\u7a0b\u76d1\u542c\u5ba2\u6237\u7aefsocket\u7684\u6d88\u606f, \u5426\u5219\u5bb9\u6613\u51fa\u9519.<\/p>\n<p>4. \u53d1\u9001\u6d88\u606f\u65f6\u4f7f\u7528\u7684\u662fsendall\u65b9\u6cd5\u800c\u975esend\u65b9\u6cd5, sendall\u662f\u5bf9send\u7684\u5305\u88c5, \u5b8c\u6210\u4e86\u7528\u6237\u9700\u8981\u624b\u52a8\u5b8c\u6210\u7684\u90e8\u5206, \u5b83\u4f1a\u81ea\u52a8\u5224\u65ad\u6bcf\u6b21\u53d1\u9001\u7684\u5185\u5bb9\u91cf, \u7136\u540e\u4ece\u603b\u5185\u5bb9\u4e2d\u5220\u9664\u5df2\u53d1\u9001\u7684\u90e8\u5206, \u5c06\u5269\u4e0b\u7684\u7ee7\u7eed\u4f20\u7ed9send\u8fdb\u884c\u53d1\u9001.<\/p>\n<p>5. \u4e00\u4e2a\u56f0\u6270\u6211\u6700\u4e45\u7684\u95ee\u9898\u8fd8\u662f\u4e00\u4e2a\u963b\u585e\u95ee\u9898, \u7ecf\u6392\u67e5, \u662fUnity\u7aef\u811a\u672c\u7684StreamReader.ReadLine()\u8bfb\u53d6socket\u5b57\u8282\u6d41\u65f6\u51fa\u73b0\u4e86\u95ee\u9898, \u82e5\u670d\u52a1\u7aef\u5728\u5411\u5ba2\u6237\u7aef\u53d1\u9001\u6d88\u606f\u65f6\u6ca1\u6709\u4ee5&#8217;\\n&#8217;\u7ed3\u5c3e, \u5219StreamReader.ReadLine()\u4f1a\u4e00\u76f4\u7b49\u5f85&#8217;\\n&#8217;\u624d\u7ed3\u675f, \u4ece\u800c\u5f15\u53d1\u4f20\u8f93\u5835\u585e\u7684\u95ee\u9898.<\/p>\n<p>\u540e\u7eed\u5b9e\u73b0\u8fc7\u7a0b\u4e2d\u53ef\u80fd\u8fd8\u4f1a\u8e29\u4e0d\u5c11\u5751, \u5982\u679c\u6709\u503c\u5f97\u8bb0\u5f55\u7684\u518d\u6765\u66f4\u65b0\u53ed~<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6700\u8fd1\u5f00\u59cb\u4f7f\u7528Python\u4e2d\u7684Socket\u7f16\u7a0b\u7740\u624b\u5b9e\u73b0Unity\u7684\u804a\u5929\u5ba4\u529f\u80fd, \u4f46\u4e4b\u524d\u81ea\u5df1\u7684\u670d\u52a1\u7aef\u7f16\u7a0b\u7ecf\u9a8c\u57fa\u672c\u4e3a &hellip; <a href=\"https:\/\/www.caiqinyi.cn\/index.php\/2020\/04\/03\/socket_chatroom\/\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">\u4f7f\u7528Python\u4e2d\u7684Socket\u7f16\u7a0b\u5b9e\u73b0Unity\u7684\u804a\u5929\u5ba4\u529f\u80fd<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18,17],"tags":[],"_links":{"self":[{"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/posts\/547"}],"collection":[{"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/comments?post=547"}],"version-history":[{"count":16,"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/posts\/547\/revisions"}],"predecessor-version":[{"id":3650,"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/posts\/547\/revisions\/3650"}],"wp:attachment":[{"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/media?parent=547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/categories?post=547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.caiqinyi.cn\/index.php\/wp-json\/wp\/v2\/tags?post=547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}