GVKun编程网logo

Python:SocketServer意外关闭TCP连接(python socket 关闭连接)

23

以上就是给各位分享Python:SocketServer意外关闭TCP连接,其中也会对pythonsocket关闭连接进行解释,同时本文还将给你拓展delphi–TTcpClient/TTcpServ

以上就是给各位分享Python:SocketServer意外关闭TCP连接,其中也会对python socket 关闭连接进行解释,同时本文还将给你拓展delphi – TTcpClient / TTcpServer和TClientSocket / TServerSocket有什么区别?、Java中使用Socket连接判断Inputstream结束,java tcp socket服务端,python tcp socket客户端、python Socket socketserver、Python SocketServer Examples等相关知识,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

Python:SocketServer意外关闭TCP连接(python socket 关闭连接)

Python:SocketServer意外关闭TCP连接(python socket 关闭连接)

我想实现一个TCP / IP网络客户端应用程序,该应用程序将请求发送到Python
SocketServer,并期望得到响应。我从正式的Python
SocketServer示例代码开始:

server.py:

#!/usr/bin/env python# encoding: utf-8import SocketServerclass MyTCPHandler(SocketServer.StreamRequestHandler):    def handle(self):        request  = self.rfile.readline().strip()        print "RX [%s]: %s" % (self.client_address[0], request)        response = self.processRequest(request)        print "TX [%s]: %s" % (self.client_address[0], response)        self.wfile.write(response)    def processRequest(self, message):        if   message == ''request type 01'':            return ''response type 01''        elif message == ''request type 02'':            return ''response type 02''if __name__ == "__main__":    server = SocketServer.TCPServer((''localhost'', 12345), MyTCPHandler)    server.serve_forever()

client.py:

#!/usr/bin/env python# encoding: utf-8import socketsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)try:    sock.connect((''127.0.0.1'', 12345))    data = ''request type 01''    sent = sock.sendall(data + ''\n'')    if sent == 0:        raise RuntimeError("socket connection broken")    received = sock.recv(1024)    print "Sent:     {}".format(data)    print "Received: {}".format(received)    data = ''request type 02''    sent = sock.sendall(data + ''\n'')    if sent == 0:        raise RuntimeError("socket connection broken")    received = sock.recv(1024)    print "Sent:     {}".format(data)    print "Received: {}".format(received)except Exception as e:    print efinally:    sock.close()

server.py 输出:

RX [127.0.0.1]: request type 01TX [127.0.0.1]: response type 01

client.py 输出:

Sent:     request type 01Received: response type 01[Errno 54] Connection reset by peer

怎么了?似乎服务器正在关闭连接。我如何使其保持打开状态?

注意:这是C ++ /
Qt的后续问题:QTcpSocket在读取后不会写入

更新(在 abarnert的回答之后):

我从中SocketServer.StreamRequestHandler得到的不是最新的设计,虽然它允许我通过网络进行连接,但是它并不能真正为我提供所有与TCP
/ IP相关的方面的支持,而这些方面需要我付诸实施。通讯。

这已在Python
3中使用asyncio解决,但由于该项目在Python
2中进行,因此这不是一个选择。因此,我已经在Twisted中实现了上述服务器和客户端:

server.py:

#!/usr/bin/env python# encoding: utf-8from twisted.internet.protocol import Factoryfrom twisted.protocols.basic import LineReceiverfrom twisted.internet import reactorclass SimpleProtocol(LineReceiver):    def connectionMade(self):        print ''connectionMade''    # NOTE: lineReceived(...) doesn''t seem to get called    def dataReceived(self, data):        print ''dataReceived''        print ''RX: %s'' % data        if   data == ''request type 01'':            response = ''response type 01''        elif data == ''request type 02'':            response = ''response type 02''        else:            response = ''unsupported request''        print ''TX: %s'' % response        self.sendLine(response)class SimpleProtocolFactory(Factory):    def buildProtocol(self, addr):        return SimpleProtocol()reactor.listenTCP(12345, SimpleProtocolFactory(), interface=''127.0.0.1'')reactor.run()

client.py:

#!/usr/bin/env python# encoding: utf-8from twisted.internet import reactorfrom twisted.internet.protocol import Protocolfrom twisted.internet.endpoints import TCP4ClientEndpoint, connectProtocolclass SimpleClientProtocol(Protocol):    def sendMessage(self, msg):        print "[TX]: %s" % msg        self.transport.write(msg)def gotProtocol(p):    p.sendMessage(''request type 01'')    reactor.callLater(1, p.sendMessage, ''request type 02'')    reactor.callLater(2, p.transport.loseConnection)point = TCP4ClientEndpoint(reactor, ''127.0.0.1'', 12345)d = connectProtocol(point, SimpleClientProtocol())d.addCallback(gotProtocol)reactor.run()

客户端不会关闭,但是直到CTRL+闲置C。Twisted可能要花点时间才能动手,但对于手头的工作,显然使用一个经过测试和尝试的框架比亲自完成所有这些基础工作更为合理。

答案1

小编典典

这里的问题是,在中TCPHandler,“请求”实际上是从头到尾的完整连接。*您的处理程序被调用accept,从中返回时,套接字被关闭。

如果要在此之上构建一个请求-响应-
协议处理程序,该处理程序在单个套接字级请求上处理多个协议级请求,则您必须自己执行此操作(或使用更高级别的框架)。(类似的子类BaseHTTPServer演示了如何执行此操作。)

例如,您可以在handle函数中使用循环。当然,您可能想要在此处添加一个异常处理程序和/或处理EOF from
rfile(注释self.rfile.readline()将返回''''EOF,但返回''\n''空行,因此您必须在调用前进行检查,strip除非您希望空行表示“退出”在您的协议中)。例如:

def handle(self):    try:        while True:            request  = self.rfile.readline()            if not request:                break            request = request.rstrip()            print "RX [%s]: %s" % (self.client_address[0], request)            response = self.processRequest(request)            print "TX [%s]: %s" % (self.client_address[0], response)            self.wfile.write(response + ''\n'')    except Exception as e:        print "ER [%s]: %r" % (self.client_address[0], e)    print "DC [%s]: disconnected" % (self.client_address[0])

通常
可以与您现有的客户端一起使用,至少可以在已卸载的计算机上通过localhost进行,但这实际上是不正确的,而且“经常工作”通常还不够好。请参阅TCP套接字是字节流,而不是消息流,以进行更长时间的讨论,但简要地说,您 需要执行David
Schwarz的回答中提到的内容:将新行添加到从服务器写入的内容(我已经在上面做过)了,并具有客户端逐行读取,而不是一次尝试读取1024个字节(您可以通过编写自己的缓冲区和分割行代码或仅通过使用makefile方法来做到这一点,因此它可以rfile.readline()像服务器一样使用边做。)

不修复客户端不会引起回答索赔的问题,但是 引起如下问题:

Sent:     request type 01Received: respSent:     request type 02Received: onse type 01response typ

您会看到,在一个实际试图以编程方式处理响应的真实程序中,类似response type 01\nresponse typ将不会非常有用的响应…


*请注意,这SocketServer是一个没人真正喜欢的古老设计。有一个添加Python 3的原因asyncio,并且Python 2中的人通常使用Twisted和gevent之类的第三方框架。对于简单任务,它们既简单,又对复杂任务更灵活/强大(并且效率更高)。

delphi – TTcpClient / TTcpServer和TClientSocket / TServerSocket有什么区别?

delphi – TTcpClient / TTcpServer和TClientSocket / TServerSocket有什么区别?

有人可以解释他们的分歧吗?它们是否相同且工作方式相同?哪一个比其他组件好?

解决方法

它们不一样,并且它们的工作方式不同.它们采用非常不同的方法来处理套接字API交互,事件处理,错误处理等.

TClientSocket和TServerSocket是原始的基于VCL(特定于Windows)的套接字组件.它们在Delphi 7中已弃用,默认情况下不再安装,但如果您想使用它们,仍可用于手动安装.

TTcpClient和TTcpserver最初是作为Kylix(这是一个死产品)的跨平台套接字解决方案在Delphi 6中引入的.它们在XE6中从Delphi中删除,降级为演示状态,甚至不再是官方组件.

在我看来,TTcpClient和TTcpserver是可怕的组件,你应该远离它们.他们使用极简主义的“最不常见的Demoninator”方法进行跨平台编程,仅适用于多个平台支持的一些基本功能,而不是利用任何特定于平台的功能甚至更高级别的功能.它们有一个设计糟糕的非常基本的界面.它们非常难以使用,具有错误的错误处理,并且使用起来不是很灵活.

如果您需要编写新的套接字代码,如果您只对支持Windows感兴趣,TClientSocket和TServerSocket工作得很好,但如果您需要支持跨平台,那么您应该使用第三方套接字库,例如Indy(TIdTCPClient / TIdTcpserver) ),ICS(TWSocket / TWSocketServer),Synapse(TTCPBlockSocket)等

Java中使用Socket连接判断Inputstream结束,java tcp socket服务端,python tcp socket客户端

Java中使用Socket连接判断Inputstream结束,java tcp socket服务端,python tcp socket客户端

        最近在试着用java写一个socket的服务器,用python写一个socket的客户端来完成二者之间的通信,但是发现存在一个问题,服务器方面就卡在读取inputsream的地方不动了,导致后面的代码没办法执行,调试许久,找到问题所在

1>python中客户端send函数发送字符串的时候没有在字符串末尾自动加换行,而我在java服务器中使用的读取函数为readline()。不难想明白二者的格   式不同,所以java一直在等换行附来完成一次读取,所以导致代码无法继续执行

2>在将python方面的字符串人为的加上换行后,java服务器单行字符串读取正常,但是出现了新问题,它不会结束读取,一直处于等待状态。百度之,发现解决这个问题的方法比较多,我采用的是超时判断的办法,即一旦读取字符串的间隔时间超时即判定为字符串传输完毕(因为我的需求比较简单,所以采用这种简陋的办法也可,实际上也可采用其他方法比如限制读取长度,比如采用特定的字符串标记结尾)。超时会弹出超时异常,捕获之并在catch中加入退出读取字符串的函数即可

JAVA SOCKET SERVER

 1 import java.io.BufferedReader;
 2 import java.io.IOException;
 3 import java.io.InputStreamReader;
 4 import java.io.PrintWriter;
 5 import java.net.ServerSocket;
 6 import java.net.Socket;
 7 import java.net.SocketException;
 8 import java.net.SocketTimeoutException;
 9  
10  
11 public class Conn extends Thread  {
12  
13     /**
14      * @param args
15      */
16     public static void main(String[] args) {
17         // TODO Auto-generated method stub
18         Conn tmp=new Conn();
19         tmp.start();
20     }
21     
22     public void run(){
23         try {
24             int i=0;
25             ServerSocket server=new ServerSocket(9998);
26             while(true){
27                 System.out.println(i++);
28                 Socket deal=server.accept();
29                 BufferedReader in=new BufferedReader(new InputStreamReader(deal.getInputStream()));
30                 PrintWriter out = new PrintWriter(deal.getOutputStream(), true); 
31                 String msg=in.readLine();
32                 while(msg!=null){
33                     try{
34                     deal.setSoTimeout(500);
35                     System.out.println(msg);
36                     msg=in.readLine();
37                     System.out.println("msg:"+msg);
38                     deal.setSoTimeout(1);
39                     }
40                     catch(SocketTimeoutException e){
41                         break;
42                     }
43                 }
44                 out.write("ok############");
45                 out.flush();
46                 in.close();
47                 out.close();
48                 deal.close();
49             }
50         } catch (IOException e) {
51             // TODO Auto-generated catch block
52             e.printStackTrace();
53             System.out.println(e.toString());
54         }
55     }
56  
57 }

 

PYTHON SOCKET CLIENT:

 1 import socket
 2 ip=''127.0.0.1''
 3 port=9998
 4 while True:
 5     time.sleep(3)#控制请求发送频率
 6     out= ''THIS IS A MSG''
 7     print out
 8     client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 9     client.connect((ip,port))
10     client.send(out+''\n'')
11     print client.recv(512)
12     client.close()

 

python Socket socketserver

python Socket socketserver

Socket

套接字

socket的 类型 实现socket对象时传入 到socket 类中

socket.AF_INET    服务器间的通讯  IPv4
socket.AF_INET6		IPv6
socket.SOCK_STREAM   流试  tcp 传输方式  默认类型
socket.SOCK_DGRAM 	 包式	 udp 传输方式

返回前端数据 需要先发送报头

b''HTTP/1/1 200 OK \r\n\r\n''

基于 Tcp 传输方式

服务端 server

import socket

server = socket.socket()
# 允许地址重用
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 绑定 ip 及 端口
server.bind(("192.168.15.100", 8001))
监听  tcp 传入链接  可设置链接个数   listen(4)
server.listen()
# 等待建立链接   conn  管道  addr 客户端的地址
conn, addr = server.accept()
#接收数据
content = conn.recv(1024).decode("utf-8")
print(content)
# 发送数据
conn.send("再见".encode("utf-8"))

# 循环发送数据  直到数据发送完毕
conn.sendall("再见..........".encode("utf-8"))
# 关闭
conn.close()
server.close()

客户端 client

import socket

clinet = socket.socket()
clinet.connect(("192.168.15.100", 8001))
clinet.send(st.encode("utf-8"))

clinet.recv(1024).decode("utf-8")

clinet.close()

基于 Udp 传输方式

服务端

import socket

server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(("127.0.0.1", 8001))
# 等待接收数据
conn, addr = server.recvfrom(1024)
st = conn.decode("utf-8")
# 向某个地址 返回数据
server.sendto(st.encode("utf-8"), addr)

客户端

import socket
clinet = socket.socket(type=socket.SOCK_DGRAM)

clinet.sendto(''你好啊!'', ("127.0.0.1", 8001))
conn, addr = clinet.recvfrom(1024)
print(conn.decode("utf-8"))

server.sendto(st.encode("utf-8"), addr)

缓冲区

作用:

​ 防止数据丢失

输入缓冲区 #recv 输出缓冲区 #send

粘包

粘包(tcp的两种粘包现象)

  1. 连续发送小的数据,并且每次发送之间的时间间隔很短(输出缓冲区:两个消息在缓冲区黏在一起了)

    原因是TCP为了传输效率,做了一个优化算法(Nagle),减少连续的小包发送(因为每个消息被包裹以后,都会有两个过程:1 组包 2拆包)

  2. 第一次服务端发送的数据比我客户端设置的一次接收消息的大小要大,那么接收不完,第二次再接收的时候,就会将第一次剩余的消息接收到

粘包的根本原因是因为:双方不知道对方发送消息的大小

  • 解决方案一:

    发送消息之前,先计算要发送消息的长度,然后先将消息长度发送过去,对方给你回一个确认收到长度的信息,然后根据接收到的消息长度来修改自己一次接收消息的大小 这个过程多了一次交互

  • 粘包解决方案二

    使用 **struct ** 模块打包

tcp和udp的区别

​ tcp协议:面向连接,消息可靠,相对udp来讲,传输速度慢,消息是面向流的,无消息保护边界0 ​ udp协议:面向无连接,消息不可靠,传输速度快,消息是面向包的,有消息保护边界.

socketserver

  • 简化网络服务端的编写

服务端 SocketServer模块与简单并发服务器

import socketserver
import struct 

class Myserver(socketserver.BaseRequestHandler):
    # 定义一个方法  handle 方法名字不可以变
    def handle(self):
        try:
            while 1:  # 循环接受 回复 数据
                # self.request 就是 conn 链接通道

                client_data = self.request.recv(1024).decode("utf-8")
                print(client_data)
                # 返回信息
                self.request.send("输入>>>".encode("utf-8"))
        except ConnectionResetError as c:
            print(c)

if __name__ == "__main__":

    server_ip = (''127.0.0.1'',8001)
    # 地址重用
    # socketserver.TCPServer.allow_reuse_address = True
    # 绑定ip 端口  启动 Myserver 类   ThreadingTCPServer>>>多线程的TCP服务端
    server = socketserver.ThreadingTCPServer(server_ip, Myserver)
    # 永久执行下去
    server.serve_forever()

FTP

#进度条打印,print版
import time
for i in range(20):
    #\r 回到行首打印内容,如果同一行有内容,那么就被抹掉了
    n = ''>'' * i
    print(''\r%s'' %n,end='''')
    time.sleep(0.5)

#进度条打印,sys版
import sys
import time
for i in range(10):
    sys.stdout.write(''>'')
    sys.stdout.flush()
    time.sleep(0.5)


#搞百分比的样子
#0.42857142857142855 改成两位数,不进行四舍五入
print(3/7) #0.42857142857142855
print(round(3/7,2)) #0.43  43%
print(int(3/7*100))

Python SocketServer Examples

Python SocketServer Examples

高春辉、王春生、朱峰:关于开源创业的 15 件小事

 

Python SocketServer Examples

Python SocketServer.TCPServer Examples

 

git 的 hook_server.py


import BaseHTTPServer
import urlparse
import time
from SocketServer import ThreadingMixIn
import threading

import os,subprocess


class WebRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_POST(self):
        self.do_GET()
    def do_GET(self):
        os.chdir("/data0/htdocs/home/")
        #os.system("git pull")
        subprocess.call("git pull", shell=True)
        content=u"OK"
        self.send_response(200)
        self.send_header("Content-type","text/html;charset=UTF-8")
        self.send_header("Content-Length",str(len(content)))
        self.end_headers()
        self.wfile.write(content)


class ThreadingHttpServer(ThreadingMixIn, BaseHTTPServer.HTTPServer):
    pass




if __name__ == ''__main__'':
    #server = BaseHTTPServer.HTTPServer((''0.0.0.0'',18460), WebRequestHandler)
    server = ThreadingHttpServer((''0.0.0.0'',8000), WebRequestHandler)
    ip, port = server.server_address
    # Start a thread with the server -- that thread will then start one
    # more thread for each request
    server_thread = threading.Thread(target=server.serve_forever)
    # Exit the server thread when the main thread terminates
    server_thread.setDaemon(True)
    server_thread.start()
    print "Server loop running in thread:", server_thread.getName()
    while True:
        pass



# class SETHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
#     def do_POST(self):
#         self.do_GET()
#     def do_GET(self):
#         os.chdir("/data0/htdocs/3d_home/")
#         #os.system("git pull")
#         subprocess.call("git pull", shell=True)
#         content=u"OK"
#         self.send_response(200)
#         self.send_header("Content-type","text/html;charset=UTF-8")
#         self.send_header("Content-Length",str(len(content)))
#         self.end_headers()
#         self.wfile.write(content)
#
# Handler = SETHandler
# PORT = 8000
# httpd = SocketServer.TCPServer(("", PORT), Handler)
# print "serving at port", PORT
# httpd.serve_forever()

 

from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler

class TestHTTPHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        buf = "It works"
        self.protocal_version = "HTTP/1.1"
        self.send_response(200)
        self.send_header("Welcome", "Contect")
        self.end_headers()
        self.wfile.write(buf)

def start_server(port):
    port=8081
    http_server = HTTPServer((''localhost'', int(port)), TestHTTPHandler)
    http_server.serve_forever()  # 设置一直监听并接收请求

start_server(8081)

 

我们今天的关于Python:SocketServer意外关闭TCP连接python socket 关闭连接的分享就到这里,谢谢您的阅读,如果想了解更多关于delphi – TTcpClient / TTcpServer和TClientSocket / TServerSocket有什么区别?、Java中使用Socket连接判断Inputstream结束,java tcp socket服务端,python tcp socket客户端、python Socket socketserver、Python SocketServer Examples的相关信息,可以在本站进行搜索。

本文标签: