鱼C论坛

 找回密码
 立即注册
查看: 1143|回复: 9

[已解决]请教个socket的问题

[复制链接]
发表于 2018-5-17 19:54:29 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 弟大勿波 于 2018-5-18 10:20 编辑

#客户端
import socket

client = socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(('localhost',6969))

while True:
    msg = input(">>:").strip()
    if len(msg) == 0:continue
    client.send(msg.encode("utf-8"))
    print(msg)
    data = client.recv(10240)
    print("recv:",data.decode())

client.close()


#服务器端

import socket
server = socket.socket()
server.bind(('localhost',6969)) #绑定要监听端口
server.listen(5) #监听

print("我要开始等电话了")
while True:
    conn, addr = server.accept()  # 等电话打进来
    # conn就是客户端连过来而在服务器端为其生成的一个连接实例
    print(conn, addr)
    print("电话来了")
    count = 0
    while True:
        data = conn.recv(1024)
        print("recv:",data)
        if not data:
            print("client has lost...")
            break
                        这一句好像没起作用
        conn.send(data.upper())
        count+=1
        if count >10:break

server.close()




为什么客户端停止的时候服务器断在data = conn.recv(1024)这一行就报错了的。ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
最佳答案
2018-5-18 10:54:17
本帖最后由 久疤K 于 2018-5-18 11:02 编辑

这不算是报错,是为了让服务端知道客户端已经强制关闭了。

服务端代码:
  1. import socket
  2. server = socket.socket()
  3. server.bind(('localhost',6969)) #绑定要监听端口
  4. server.listen(5) #监听

  5. print("我要开始等电话了")
  6. while True:
  7.     conn, addr = server.accept()  # 等电话打进来
  8.     # conn就是客户端连过来而在服务器端为其生成的一个连接实例
  9.     print(conn, addr)
  10.     print("电话来了")
  11.     count = 0
  12.     while True:
  13.         try:
  14.             data = conn.recv(1024)
  15.             data = data.decode()
  16.             print("recv:",data)
  17.         except ConnectionResetError:
  18.             data = None
  19.         if not data or data=='over':
  20.             print("client has lost...")
  21.             conn.close()
  22.             break                        #这一句好像没起作用
  23.         conn.send(data.upper().encode('utf-8'))
  24.         count+=1
  25.         if count >10:break

  26. server.close()
复制代码


客户端代码:
  1. import socket

  2. client = socket.socket() #声明socket类型,同时生成socket连接对象
  3. client.connect(('localhost',6969))

  4. while True:
  5.     msg = input(">>:").strip()
  6.     if len(msg) == 0:continue
  7.     client.send(msg.encode("utf-8"))
  8.     print(msg)
  9.     if msg == 'over':
  10.         client.close()
  11.         break
  12.     data = client.recv(10240)
  13.     print("recv:",data.decode())

  14. client.close()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-5-17 20:03:20 | 显示全部楼层
看网上的教程都这么写的呀。。直接复制源码也会报错。是3.6修改了什么么?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-17 21:53:44 | 显示全部楼层
有木有人~~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-18 10:19:40 | 显示全部楼层
还是会有这个问题。。网上的源码都试了下
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-18 10:54:17 | 显示全部楼层    本楼为最佳答案   
本帖最后由 久疤K 于 2018-5-18 11:02 编辑

这不算是报错,是为了让服务端知道客户端已经强制关闭了。

服务端代码:
  1. import socket
  2. server = socket.socket()
  3. server.bind(('localhost',6969)) #绑定要监听端口
  4. server.listen(5) #监听

  5. print("我要开始等电话了")
  6. while True:
  7.     conn, addr = server.accept()  # 等电话打进来
  8.     # conn就是客户端连过来而在服务器端为其生成的一个连接实例
  9.     print(conn, addr)
  10.     print("电话来了")
  11.     count = 0
  12.     while True:
  13.         try:
  14.             data = conn.recv(1024)
  15.             data = data.decode()
  16.             print("recv:",data)
  17.         except ConnectionResetError:
  18.             data = None
  19.         if not data or data=='over':
  20.             print("client has lost...")
  21.             conn.close()
  22.             break                        #这一句好像没起作用
  23.         conn.send(data.upper().encode('utf-8'))
  24.         count+=1
  25.         if count >10:break

  26. server.close()
复制代码


客户端代码:
  1. import socket

  2. client = socket.socket() #声明socket类型,同时生成socket连接对象
  3. client.connect(('localhost',6969))

  4. while True:
  5.     msg = input(">>:").strip()
  6.     if len(msg) == 0:continue
  7.     client.send(msg.encode("utf-8"))
  8.     print(msg)
  9.     if msg == 'over':
  10.         client.close()
  11.         break
  12.     data = client.recv(10240)
  13.     print("recv:",data.decode())

  14. client.close()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-18 10:57:58 | 显示全部楼层

你好,谢谢回复。但是我测试的还是报错。先运行服务器 再运行客户端,然后停止客户端就报错了又。
TIM截图20180518105651.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-18 11:03:09 | 显示全部楼层
弟大勿波 发表于 2018-5-18 10:57
你好,谢谢回复。但是我测试的还是报错。先运行服务器 再运行客户端,然后停止客户端就报错了又。

我更新了我在 5 楼的回答,希望对你有帮助。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-5-18 11:47:25 | 显示全部楼层
久疤K 发表于 2018-5-18 11:03
我更新了我在 5 楼的回答,希望对你有帮助。

恩恩。谢谢。加一个try确实解决了这个问题。就是让服务器一直运行等待客户端来连接。但是客户端停止的时候应该返回的就是一个Note才对呀。我看网上的文章也都是没有加try。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-5-18 12:28:46 | 显示全部楼层
弟大勿波 发表于 2018-5-18 11:47
恩恩。谢谢。加一个try确实解决了这个问题。就是让服务器一直运行等待客户端来连接。但是客户端停止的时 ...

是的,如果客户端先调用client.close(),name服务端就在获取的时候返回None。
你可以测试下,那就是正常流程关闭。
如果你一定要不用try来解决客户端关闭窗口的问题,可以试试下面的代码。
仅限于客户端使用Windows直接点击运行的情况。

服务端程序:
  1. import socket
  2. server = socket.socket()
  3. server.bind(('localhost',6969)) #绑定要监听端口
  4. server.listen(5) #监听

  5. print("我要开始等电话了")
  6. while True:
  7.     conn, addr = server.accept()  # 等电话打进来
  8.     # conn就是客户端连过来而在服务器端为其生成的一个连接实例
  9.     print(conn, addr)
  10.     print("电话来了")
  11.     count = 0
  12.     while True:
  13.         data = conn.recv(1024)
  14.         if data:
  15.             data = data.decode()
  16.         print("recv:",data)
  17.         if not data or data=='over':
  18.             print("client has lost...")
  19.             conn.close()
  20.             break                        #这一句好像没起作用
  21.         conn.send(data.upper().encode('utf-8'))
  22.         count+=1
  23.         if count >10:break

  24. server.close()
复制代码

客户端程序:
  1. import socket
  2. import win32api

  3. client = socket.socket() #声明socket类型,同时生成socket连接对象
  4. client.connect(('localhost',6969))

  5. def on_close(sig):
  6.     client.close()

  7. win32api.SetConsoleCtrlHandler(on_close, True)

  8. while True:
  9.     msg = input(">>:").strip()
  10.     if len(msg) == 0:continue
  11.     client.send(msg.encode("utf-8"))
  12.     print(msg)
  13.     if msg == 'over':
  14.         client.close()
  15.         break
  16.     data = client.recv(10240)
  17.     print("recv:",data.decode())

  18. client.close()
复制代码

但是强烈建议服务端使用try的形式来解决,因为你永远不知道客户端是否走正常流程,即使看起来客户端是你写的。

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
弟大勿波 + 5 + 5 + 3 感谢楼主无私奉献!

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2018-5-18 12:40:17 | 显示全部楼层
久疤K 发表于 2018-5-18 12:28
是的,如果客户端先调用client.close(),name服务端就在获取的时候返回None。
你可以测试下,那就是正常 ...

非常感谢。原来是客户端要.close()关闭才会返回Note。
开心每一天
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-10-23 03:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表