点我
点我
文章目录
  1. 多线程版本服务器端程序server2.py
  2. 改良版,带广播的聊天室程序server3.py
  3. 客户端程序client3.py
  • 参考文献
  • python学习笔记--socket编程端口复用

    最近在学习socket编程,遇到一个问题:
    我先bind一个端口后,如果通过ctr+c关闭进程.接下来执行程序的时候,就会提示socket.error: Address already in use.

    照例google一番,找到这个.博主说的情况和我的一样.
    我还在stackoverflow上找到这个.
    修改后代码如下:

    1
    2
    3
    4
    5
    6
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 下面这行是关健
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    server_socket.bind(('', PORT))
    server_socket.listen(5)

    然后就搞定了.

    下面的代码是socket编程敲得两个小例子,基于socket的聊天小程序都是别人的东西,只是练习一下,源地址在本文最后.

    多线程版本服务器端程序server2.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    # !/usr/bin/env python
    # -*- coding:utf-8-*-
    __author__ = 'chen'


    import socket,sys
    from thread import *

    HOST = ''
    PORT = 8888

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print 'socket created'

    try:
    s.bind((HOST, PORT))
    except socket.error, msg:
    print 'bind failed.Error code: |||%S Message: %s' %(str(msg[0]), msg[1])
    sys.exit()


    print 'socket bind complete'

    s.listen(10)
    print 'socket now listening'

    def clientthread(conn):
    conn.send('welcome to the server.Type something and hit enter\n')

    while True:
    data = conn.recv(1024)
    reply = 'ok...' + data
    if not data:
    break
    conn.sendall(reply)
    conn.close()

    while 1:
    conn, addr = s.accept()
    print 'connected with %s : %s' %(addr[0],str(addr[1]))

    start_new_thread(clientthread, (conn,))

    s.close()

    直接telnet连接socket,就可以调试

    1
    telnet localhost 8888

    改良版,带广播的聊天室程序server3.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    # !/usr/bin/env python
    # -*- coding:utf-8-*-
    __author__ = 'chen'

    import socket, select

    def broadcast_data(sock, message):
    for socket in CONNECTION_LIST:
    if socket != server_socket != sock:
    try:
    socket.send(message)
    except msg:
    socket.close()
    CONNECTION_LIST.remove(socket)

    if __name__ == "__main__":
    CONNECTION_LIST = []
    RECV_BUFFER = 4096
    PORT = 5000
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(('', PORT))
    server_socket.listen(5)

    CONNECTION_LIST.append(server_socket)
    print "chat server started on port %s" % str(PORT)

    while 1:
    read_sockets, write_sockets,error_sockets = select.select(CONNECTION_LIST, [], [])

    for sock in read_sockets:
    if sock == server_socket:
    sockfd,addr = server_socket.accept()
    CONNECTION_LIST.append(sockfd)
    print "client (%s, %s) connected" % addr

    broadcast_data(sockfd, "[%s:%s] entered room\n" % addr)

    else:
    try:
    data = sock.recv(RECV_BUFFER)
    if data:
    print "[%s:%s]" % (str(sock.getpeername()), data)
    broadcast_data(sock, "[%s:%s]" % (str(sock.getpeername()), data))
    except msg:
    print msg
    broadcast_data(sock, "client (%s, %s) is offline "% addr)
    print "client (%s,%s) is offline " % addr
    sock.close()
    CONNECTION_LIST.remove(sock)
    continue
    server_socket.close()

    客户端程序client3.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    # !/usr/bin/env python
    # -*- coding:utf-8-*-
    __author__ = 'chen'

    import socket,select,string,sys

    def prompt():
    sys.stdout.write('[you]')
    sys.stdout.flush()

    if __name__ == "__main__":
    if(len(sys.argv)<3):
    print 'usage: python client3.py hostname port'
    sys.exit()

    host = sys.argv[1]
    port = int(sys.argv[2])

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(2)

    try:
    s.connect((host, port))
    except:
    print 'unable to connect'
    sys.exit()

    print 'connected to remote host. start sending messages'
    prompt()

    while 1:
    rlist = [sys.stdin, s]

    read_list, write_list, error_list = select.select(rlist, [], [])

    for sock in read_list:
    if sock == s:
    data = sock.recv(4096)
    if not data:
    print '\nDisconnected from chat server'
    sys.exit()
    else:
    sys.stdout.write(data)
    prompt()

    else:
    msg = sys.stdin.readline()
    s.send(msg)
    prompt()

    参考文献

    1 Python Socket 网络编程
    2 Python Socket 编程——聊天室示例程序

    支持一下
    扫一扫,试试看
    • 微信扫一扫
    • 支付宝扫一扫