客户端套接字在客户端突然关闭后停止工作

时间:2018-05-05 10:24:09

标签: python-sockets

服务器代码开始监听。当我在客户端做F5并等待时,代码运行得很好。如果我再次尝试F5,在上一次尝试连接的过程中,客户端程序无法建立连接(s == None),我需要解决这个问题,特别是因为无论何时我再次运行客户端,它都会停留显示相同的问题以建立连接。在其他工作中,我需要重新启动服务器程序。 在其他调试中,我知道它的工作方式不正常,IDLE打印" q" s 20次然后

  

无法打开套接字

     

无法读取结果。

我接受任何有关我编码的建设性批评。编程对我来说只是一个爱好。这是我的两个代码:

服务器代码

import socket
import sys
import multiprocessing as mp
import time
import psycopg2 as psy

print("server is on!")
HOST = None
PORT = 50007

process = []

def checkin_room(room, passw, user, ip, port):
    print("main:checkin_room")
    conn = psy.connect("host=localhost dbname=pychat user=root password=codigo64")
    cr = conn.cursor()
    cr.execute("select * from rooms where name = '%s';")
    row = cr.fetchone()
    print("main: here")
    if row == None:
        cr.execute("insert into rooms (name,hashpw) values ('%s','%s');"%(room,passw))
        cr.execute("select id from rooms where name = '%s';"%(room))
        rid = cr.fetchone()[0]
        cr.execute("insert into users (rid,name,ip,port) values (%d,'%s','%s',%d);"%(rid,user,ip,port))
        print("new room")
        return 1 # room created
    else:
        cr.execute("select * from rooms where name = '%s' and hashpw = '%s';"%(room,passw))
        row = cr.fetchone()
        if row == None:
            print("wrong password for room")
            return 0 # wrong password
        else:
            cr.execute("select ip, port from users where rid = %d and ip != '%s';"%(row[0],ip))
            row = cr.fetchall()
            if row == None:
                print("no users in room")
                return []
            print("other users in room")
            return row # correct password: return ip and ports of users from room


def check_socket():
    print("Socket's being checked.")
    while True:
        s = None
        for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                                      socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
            af, socktype, proto, canonname, sa = res
            try:
                s = socket.socket(af, socktype, proto)
            except OSError as msg:
                s = None
                continue
            try:
                s.bind(sa)
                s.listen(1)
            except OSError as msg:
                s.close()
                s = None
                continue
            break
##        if s is None:
##            print('could not open socket')
##            sys.exit(1)
        if s != None:
            conn, addr = s.accept()
            try:
                ip, port = addr
            except:
                print("problem: ",addr)
                s.close()
                s = None
                continue
            with conn:
                print('Connected by', addr)
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    cmd = eval(data.decode("utf-8"))
                    if cmd[0] == "checkin":
                        ret = checkin_room(cmd[1],cmd[2],cmd[3],ip,port)
                        conn.sendall(str(ret).encode("utf-8"))
            s.close()


process.append(mp.Process(target = check_socket))
process[-1].start()
print("process started...")
time.sleep(1)
print("Command line ready for use.")
while True:
    cmd = input()
    if cmd == "end":
        for p in process:
            p.terminate()
        break
print("Program's over.")

客户端代码

import socket, sys

HOST = "123.123.123.123" # fake host
PORT = 50007

ROOM = "ufrj"
PASSW = "fundao"
USER = "coresh"

friends = []


def send_server(host, port, cmd):
    s = None
    print("client: here1")
    for i in range(20):
        for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM):
            af, socktype, proto, canonname, sa = res
            try:
                s = socket.socket(af, socktype, proto)
            except socket.error as msg:
                s = None
                continue
            try:
                s.connect(sa)
            except socket.error as msg:
                s.close()
                s = None
                continue
            break
        if s == None:
            print("qq")
        else:
            break
    if s is None:
        print ('could not open socket')
        return
    print("client: here2")
    s.sendall(bytearray(str(cmd).encode("utf-8")))
    print("here3")
    data = s.recv(1024)
    print("here4")
    s.close()
    print("closed")
    return eval(data.decode("utf-8"))


def checkin_room(room, passw, user):
    cmd = ["checkin", room, passw, user]
    ret = send_server(HOST, PORT, cmd)

    if ret == 1:
        print("Room's been created.")

    elif ret == 0:
        print("Wrong password.")

    elif type(ret) == list:
        if ret == []:
            print("Only you in the room.")
        else:
            friends += ret

    else:
        print("Can't read result.")

checkin_room(ROOM, PASSW, USER)

1 个答案:

答案 0 :(得分:0)

再次按F5时,您正在执行的操作是在不先关闭套接字的情况下切断程序。这导致它挂起,您不能再次使用该套接字。重新启动程序之前,使客户端进入s.close()。这将完全关闭插槽,并阻止插槽挂起。

关于编码方式,请尝试在每行代码之间插入空白行。这将帮助您阅读和调试代码。