004---基于TCP的套接字

Posted xjmlove

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了004---基于TCP的套接字相关的知识,希望对你有一定的参考价值。

基于TCP的套接字

tcp是基于链接的,必须先启动服务端,然后再启动客户端去连接服务端。
之前实现的简单套接字就是基于TCP的,但是只能实现收发消息一次、服务器与客户端都断开了。不够过瘾。

通信循环版本

服务端

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "ziya"
# Date: 2019-02-01

import socket

ip_port = ('127.0.0.1', 8000)
buffer_size = 1024

service = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

service.bind(ip_port)

service.listen(5)

conn, addr = service.accept()

# 通信循环(c/s之间不只收发一次消息)
while 1:
    msg = conn.recv(buffer_size)
    print('客户端发来的消息:', msg.decode('utf-8'))
    data = input('给客户端发的消息:')
    conn.send(data.encode('utf-8'))
    print('发生给客户端的消息成功:', data)

conn.close()

sk.close()

客户端

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "ziya"
# Date: 2019-02-01

import socket

ip_port = ('127.0.0.1', 8000)
buffer_size = 1024

client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

client.connect(ip_port)

while 1:
    msg = input('输入发给服务端的消息:').strip()
    client.send(msg.encode('utf-8'))
    data = client.recv(buffer_size)
    print('服务端回复的消息:', data.decode('utf-8'))

client.close()

技术分享图片
技术分享图片
从图中可以看出有bug,当客户端强制端口连接,服务器那边会抛出异常。
还有就是客户端发送不了空消息(空格)。

小Bug修复

服务端

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "ziya"
# Date: 2019-02-01

import socket

ip_port = ('127.0.0.1', 8000)
buffer_size = 1024

service = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

# 有时候会出现端口占用的情况,加上下面代码
service.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

service.bind(ip_port)

service.listen(5)

conn, addr = service.accept()

# 通信循环(c/s之间不只收发一次消息)
while 1:
    try:
        msg = conn.recv(buffer_size)
        if not msg:
            print('客户端主动退出')
            break
        print('客户端发来的消息:', msg.decode('utf-8'))
        data = input('给客户端发的消息:')
        conn.send(data.encode('utf-8'))
        print('发生给客户端的消息成功:', data)
    except ConnectionResetError as con:
        print('客户端强制退出')
        break
conn.close()

service.close()

客户端

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "ziya"
# Date: 2019-02-01

import socket

ip_port = ('127.0.0.1', 8000)
buffer_size = 1024

client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

client.connect(ip_port)

while 1:
    msg = input('输入发给服务端的消息(q/Q退出):').strip()
    if not msg:
        print('不能发送空消息给服务器')
        continue
    if msg.upper() == 'Q':
        print('正在主动退出')
        break
    client.send(msg.encode('utf-8'))
    data = client.recv(buffer_size)
    print('服务端回复的消息:', data.decode('utf-8'))

client.close()
print('exit ok')

技术分享图片
技术分享图片
技术分享图片
技术分享图片

连接循环版本

虽然没啥大问题。但是还有一个大问题,就是只能有一个客户端连接。客服端正常断开或者强制断开,服务器也会跟着断,并不能保证其他客户端来连接。

服务器

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "ziya"
# Date: 2019-02-01

import socket

ip_port = ('127.0.0.1', 8000)
buffer_size = 1024

service = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

# 有时候会出现端口占用的情况,加上下面代码
service.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

service.bind(ip_port)

service.listen(5)

while 1:
    # 连接循环(客户端断开之后其他客户端还能连接。
    conn, addr = service.accept()
    while 1:
        # 通信循环(c/s之间不只收发一次消息)
        try:
            msg = conn.recv(buffer_size)
            if not msg:
                print('客户端主动退出')
                break
            print('客户端发来的消息:', msg.decode('utf-8'))
            data = input('给客户端发的消息:')
            conn.send(data.encode('utf-8'))
            print('发生给客户端的消息成功:', data)
        except ConnectionResetError as con:
            print('客户端强制退出')
            break
    conn.close()

service.close()

客户端

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# __author__ = "ziya"
# Date: 2019-02-01

import socket

ip_port = ('127.0.0.1', 8000)
buffer_size = 1024

client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

client.connect(ip_port)

while 1:
    msg = input('输入发给服务端的消息(q/Q退出):').strip()
    if not msg:
        print('不能发送空消息给服务器')
        continue
    if msg.upper() == 'Q':
        print('正在主动退出')
        break
    client.send(msg.encode('utf-8'))
    data = client.recv(buffer_size)
    print('服务端回复的消息:', data.decode('utf-8'))

client.close()
print('exit ok')

以上是关于004---基于TCP的套接字的主要内容,如果未能解决你的问题,请参考以下文章

基于TCP的客户端服务器端socket编程

基于TCP通信的套接字

基于套接字通信(tcp)

套接字编程——基于TCP协议

iOS 上的 VoIP 套接字 - 未收到通知

基于TCP协议的socket套接字编程