精华内容
下载资源
问答
  • linux程序多线程socket程序出现断开的管道 <br />问题描述: <br />socket在侦听情况下,接受一个外部的socket,但是还没有处理。之后该socket已经断开,但是程序却继续处理这个socket,此时会导致...

    linux程序多线程socket程序出现断开的管道

    问题描述:

    socket在侦听情况下,接受一个外部的socket,但是还没有处理。之后该socket已经断开,但是程序却继续处理这个socket,此时会导致程序处理一个断开的socket,程序退出。

    处理方法:

    在程序中添加:

    struct sigaction action;                    //信号处理结构体
    action.sa_handler = function;         //产生信号时的处理函数
    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;
    sigaction(SIGPIPE,&action,NULL); //信号类型
    function是捕捉到的处理函数。

    function函数可以不做任何处理,但是该函数需要存在。

    这样处理后,程序就不会退出了。

    void SetupSignal(void)
    {
      struct sigaction act;

      act.sa_handler = signal_catch;
      act.sa_flags   = 0;
      sigemptyset(&act.sa_mask);
      sigaction(SIGHUP,&act,NULL);
      sigaction(SIGINT,&act,NULL);
      sigaction(SIGQUIT,&act,NULL);
      sigaction(SIGILL,&act,NULL);
      sigaction(SIGABRT,&act,NULL);
      sigaction(SIGIOT,&act,NULL);
      sigaction(SIGBUS,&act,NULL);
      sigaction(SIGFPE,&act,NULL);
      sigaction(SIGTERM,&act,NULL);
    }

    static void signal_catch(int signo)
    {
      time_t now;

      close(DaemonSocket);
      if (ClientSocket>0) close(ClientSocket);
      CleanLock();
      now = time(NULL);
      dlog("Catch signal %d, leave at %s/n",signo,asctime((const struct tm*)localti
      exit(-1);

    展开全文
  • recv()退出线程

    千次阅读 2013-04-26 14:15:29
    在recv()在等待数据时,由于对方断开,造成recv()返回SIGPIPE,造成退出进程。 send()也会遇到相同问题,当服务器close一个连接时,若client端接着发数据。根据TCP协议的规定,会收到一个RST响应,client再往...

    今天遇到recv()过程中,退出程序问题

    在recv()在等待数据时,由于对方断开,造成recv()返回SIGPIPE,造成退出进程。

    send()也会遇到相同问题,当服务器close一个连接时,若client端接着发数据。根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出),所以client会退出。若不想客户端退出可以把SIGPIPE设为SIG_IGN(表示忽略此信号)。


        如:    signal(SIGPIPE,SIG_IGN);
        这时SIGPIPE交给了系统处理。

      服务器采用了fork的话,要收集垃圾进程,防止僵尸进程的产生,可以这样处理:
      signal(SIGCHLD,SIG_IGN); 交给系统init去回收。
       这里子进程就不会产生僵尸进程了。



    展开全文
  • python 多线程服务器验证,实现断开重连,信号量解决主线程Ctrl+C不退出问题,多线程打印错行问题 基本是解决了本人困扰已久的问题。。

    最近在做一个比赛

    有道题给了一个字典,user和pass都在字典中

    服务器没有验证码

    摆明了要用脚本跑username和password

    顺便把以前想实现的给实现了。。

    人生啊,不要拖拖拉拉



    零、遇到的问题:

    1、脚本跑着跑着就断线了,怎么重连呢?

    2、主线程按Ctrl+C,不能退出

    3、多线程打印错行,不能老实的一行一行地打印


    一、脚本跑着跑着就断线了,怎么重连呢?

    把多线程中的调用函数如def login()加一个try except,在except中重新调用login()即可

    为了更加人性化,加入了两个标记变量i和j(也就是start_user和start_pass),标记从i和j处重新跑



    二、主线程按Ctrl+C,不能退出

    这个Ctrl+C比较棘手,参考文章:http://my.oschina.net/apoptosis/blog/125099

    主要用信号量的方法,分6个小步骤来解决就好了:

    1、

    定义一个全局变量:is_exit = False

    2、

    定义一个处理变量的函数:

    def handler(signum,frame):
        global is_exit
        is_exit = True
        tstr = "receive a signal %d,is_exit = %d \n" % (signum,is_exit)
        sys.stdout.write(tstr)
    3、

    在main函数中注册信号捕捉函数:

        #修改is_exit信号,让子线程也能接受Ctrl+C
        #用函数signal注册一个信号捕捉函数,捕捉到后交给handle去处理
        signal.signal(signal.SIGINT,handler)
        signal.signal(signal.SIGTERM,handler)



    4、

    在子线程函数,本例子中是login(),添加处理信号变更的处理:

                #修改全局变量,接受到Ctrl+C,is_exit就会变成True,就会退出
                if is_exit:
                    tstr = "thread"+str(index)+", receive a signal to exit...\n" 
                    sys.stdout.write(tstr)
                    return



     
    5、

    将子线程设置为后台运行

    tmpth = threading.Thread(target = login,args=(i,0,0,))
    tmpth.setDaemon(True)

    6、

    修改tmpth.join()

    为自定义的等待代码:

        #for i in range(th_num):
        #    ths[i].join()
    
        while True:
            alive = False
            for i in range(th_num):
                alive = alive or ths[i].isAlive()
            if not alive:
                break


    实际上结果是良好的:



    三、多线程打印错行,不能老实的一行一行地打印

    错行的效果如下:


    看到没有,都不能老老实实得在一行行来吗?
    然后在CSDN发帖子询问,得知要用:
    sys.stdout.write(str+'\n') 
    代替:
    print str
    好吧,效果果然很不错,可以参照上上图(不是上图,我不是大舌头)

    那么,为什么呢?

    python shell 下help(print) ,它说print是输出到sys.stdout 中,也是调用write

    一样的函数,不一样的效果,我怀疑是print没有维护一个buffer,而sys.stdout.write的时候有维护,导致了

    前者竞争输出,后者有个缓冲区导致输出很规整。(以上纯属猜想,因为py文档英文也看不懂,网上也没有好资料,实验也不好做。。)


    四、所有的代码

    本来py就是强调精短,而我却弄这么多。。
    好吧,难道我会告诉你其实如果不考虑:
    多线程,print,Ctrl+C,重连
    我的代码会很短吗?

    # -*- coding: cp936 -*-
    import urllib
    import httplib
    import base64
    import threading
    import sys,os,time,signal
    
    #导入dic字典
    f = open('youcanfindit.dic','r')
    dic = []
    while True:
        t = f.readline()
        if not t:
            break
        dic.append(t.strip('\n'))
    f.close()
    
    
    #只需要输入th线程数量,程序自动配置后每个线程的case数
    #比如某些高富帅的线程可以设置为100,我的最高只能40,否则内存就不够用了。。
    #这里强调,不是线程越多越快,线程多,只是说开始办事的人很多,每个人平摊下来任务少了,没说任务效率变快
    #请考虑py的调度,每个时刻只有一个线程在运行,调度的时间大大增多,这是个综合考虑的问题
    th_num = 10
    dic_len = len(dic)
    case_in_th_num = dic_len/th_num
    case_in_last_th_num = dic_len - th_num * case_in_th_num
    
    #响应Ctrl+C
    is_exit = False
    def handler(signum,frame):
        global is_exit
        is_exit = True
        tstr = "receive a signal %d,is_exit = %d \n" % (signum,is_exit)
        sys.stdout.write(tstr)
    
    #支持断线重连,start_user 和 start_pass 标记了user和pass重连的位置
    def login(index,start_user,start_pass):
        global is_exit    
    
            
        if index == th_num-1:
            name = dic[case_in_th_num*index:case_in_th_num*index+case_in_last_th_num]
        else:
            name = dic[100*index:100*index+100]
        for i in range(start_user,len(name)):
            for j in range(len(dic)):
                #修改全局变量,接受到Ctrl+C,is_exit就会变成True,就会退出
                if is_exit:
                    tstr = "thread"+str(index)+", receive a signal to exit...\n" 
                    sys.stdout.write(tstr)
                    return
        
                #记录断线的i(user)和j(pass),从i重新跑一遍,j依赖于i
                if i == start_user:
                    if j < start_pass:
                        continue
                    
                name_pass = base64.b64encode(name[i]+':'+dic[j])
                headers = {
                'Host': 'wocao.ismilent.com',
                'Connection': 'keep-alive',
                'Cache-Control':'max-age=0',
                'Authorization' : 'Basic '+name_pass,
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
                'Accept-Encoding': 'gzip,deflate,sdch',
                'Accept-Language': 'zh-CN,zh;q=0.8'
                }
                try:
                    conn = httplib.HTTPConnection('wocao.ismilent.com',80)
                    conn.request('GET','',None,headers)
                    res = conn.getresponse()
                    tstr = str(index)+","+str(i)+":"+str(j)+"--"+name[i]+":"+dic[j]+"\n"
                    sys.stdout.write(tstr)
                    
                    if res.reason != 'Unauthorized':
                        print res
                        out = open('out.txt','w')
                        out.write(name[i]+":"+dic[j])
                        out.close()
                        print name[i],dic[j],'!!!!!!!!!!!!!Success!!!Finished...!!!!!!!!!!!!!'
                        exit(-2)
                except:
                    #断线重连,记录i,j
                    #这里注意如果获取到了name和pass,那么会进去if res.reason != 'Unauthorized':中
                    #然后弹出个框框问你是否要结束,如果点击否,会触发异常
                    #进入这里的login,那么i,j又是原来的那个正确的user pass 又会问你是否退出,以下循环!
                    #这不是bug!!!
                    tstr = "reconnecting..."+str(i)+":"+str(j)+"\n"
                    sys.stdout.write(tstr)
                    #login(index,i,j)
    
    
     
    
    if __name__ == '__main__':
        #修改is_exit信号,让子线程也能接受Ctrl+C
        signal.signal(signal.SIGINT,handler)
        signal.signal(signal.SIGTERM,handler)
        
        ths = []
        for i in range(th_num):
            print 'threading '+str(i)
            tmpth = threading.Thread(target = login,args=(i,0,0,))
            tmpth.setDaemon(True)
            ths.append(tmpth)
            tmpth.start()
        
        #for i in range(th_num):
        #    ths[i].join()
    
        while True:
            alive = False
            for i in range(th_num):
                alive = alive or ths[i].isAlive()
            if not alive:
                break
            
        print '!!!!!!!!!!Sorry,find nothing,finished!!!!!!!!!'
    


    展开全文
  • tcp client基于tcp简单的控制台实例 连接,发送,接收,断开,多线程
  • 1.使用setDaemon(True)代替join() 【全部替换】---不然子线程2.在主线程try: while True: time.sleep(1) except KeyboardInterrupt:  # 使用文件内容来判断是否关闭tcpsocketserver连接  with open('文件路径','...

    1.使用setDaemon(True)代替join() 【全部替换】---不然子线程

    2.在主线程

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        # 使用文件内容来判断是否关闭tcpsocketserver连接
        with open('文件路径','w') as f:
            f.write('0')
    print('main end')

    3.tcpsocketserver

    def __init__(self, request, client_address, server):
        self.request = request
        self.client_address = client_address
        self.server = server
        self.setup()
        try:
            self.handle()
        finally:
            self.finish()
    
    
    def setup(self):
        ip = self.client_address[0].strip()     # 获取客户端的ip
        port = self.client_address[1]           # 获取客户端的port
        print('ServerTCPForDev %s:%d is connected!' % (ip, port))
    
    def handle(self):
        while True:
            with open('文件路径','r') as f:
                if int(f.read()) == 1:
                    print('client tcp  ',self.client_address, ' 工作正常')
                    # 给recv设置一个时间,如果超过了这个时间,就执行这个判断方法
                    data = self.request.recv(1024)
                    print('recv from client is %s' % data.decode())
                else:
                    print('server',self.server, ' 即将断开连接' )
                    self.server.shutdown() # 关闭服务端连接
                    self.request.close()  # 关闭客户端连接
                    break  
    def finish(self):
        ip = self.client_address[0].strip()     # 获取客户端的ip
        port = self.client_address[1]           # 获取客户端的port
        print("tcp client(%s:%d) is disconnect!" % (ip, port))

    客户端代码

    import socket
    import time
    from threading import Thread
    
    port = 10501
    
    class ClientThread(Thread):
        def __init__(self):
            super(ClientThread, self).__init__()
        def run(self):
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((host, port))
            try:
                while True:
                    s.sendall('nihao'.encode('utf-8'))
                    time.sleep(3)
            except:
                s.close()
    
    for i in range(4):
        a = ClientThread()
        a.start()


    展开全文
  • tcp断开导致进程退出

    2020-04-26 21:43:23
    问题出现的情景及表现 最近写一个网络应用,里面...后来修改客户端代码,希望在客户端发现连接异常或断开时能间隔10秒再从新连接,这样客户端主体其实是个无限循环,不应该会有退出。 测试发现当运行中如果直接关闭...
  • 基于Qt的线程安全退出

    千次阅读 2018-06-06 15:24:21
    最近,在线程退出时,老是会遇到程序异常问题。为此,对于QThread的线程退出,做了详细的测试,并将测试结果做个总结。首先,QThread的用法有两种:(1)继承自QThread类:#ifndef CHILDTHREADA_H#define ...
  • 这里自己写了个JDBC心跳检测及断开重连线程: 运行截图如下: 心跳的时候运行ipconfig /release 然后再给他ipconfig /renew回去: 关键代码如下: Maven: <?xml version="1.0" encoding="UTF-8"?> ...
  • 线程退出优化

    2013-07-10 20:51:04
    监控客户端支持同时播放最大8路视频,每个设备有个CCamera类对其进行抽象,CCamera中有工作线程进行视频收发和... 停止接受视频数据,断开和设备的网络连接 清除队列中的帧数据 清除未完成的任务 最初设计是串行执行的
  • send函数引发线程退出

    2017-04-01 10:46:46
    在linux下进行send函数通信时,客户端断开socket,偶尔会导致服务端线程退出,通过网上查找资料,并参考了http://blog.csdn.net/think_nothing/article/details/17006179 得出退出原因,总结如下: 在linux下...
  • 文章目录Linux线程1、简单了解一下线程2、线程创建:pthread_create3、线程传参注意事项4、线程退出:pthread_exit5、线程回收:pthread_join6、线程分离:pthread_detach7、线程取消:pthread_cancel8、线程其他...
  • 智能家居 (4) ——网络控制端线程

    千次阅读 2021-02-22 21:35:56
    线程控制——远程网络控制(调试):(1)main.c 文件(主函数) 1.工厂模式创建远程网络控制对象: (1)socketControl.c 文件(网络远程控制) (2)command.h 文件(指令方式类) 2.多线程控制——远程网络控制...
  • 因为之前遇到了 断开第一次链接后,再想链接就再也链接不上的问题。 最后查到因为我的io_service没有构造出一个 work, boost::io_serivice 需要有个io_service::work来keep住, 如果没有work,在一次启动...
  • 线程都是一样的, 退出了一个不会影响另外一个。 但是所谓的"主线程"main,其入口代码是类似这样的方式调用main的:exit(main(…))。 main执行完之后, 会调用exit()。 exit() 会让整个进程over终止,那所有线程自然...
  • Boost.Asio 有两种支持多线程的方式,第一种方式比较简单:在多线程的场景下,每个线程都持有一个io_service,并且每个线程都调用各自的io_service的run()方法。  另一种支持多线程的方式:全局只分配一个io_...
  • 线程网络通信

    千次阅读 2010-10-27 22:49:00
    最近写一个多线程网络通信DLL,原来认为自己的网络通信这一方面水平即使不是杠杠滴,也得当当滴,至不成也得忽忽滴。结果真得一写起来,发现很多东西都吃不透,都懂,都明白大其概,但真正应用哪种更好,哪...
  • socket: 调用send 线程异常退出问题

    千次阅读 2018-11-27 11:37:12
    ssize_t send(int sockfd, const void *buf, ...如果是flag==0, 如果断开连接,这调用send,线程会异常退出. (1)解决方法设置以下flag, 或者重新处理SIGPIPE也可以解决. MSG_NOSIGNAL (since Linux 2.2)  ...
  • 考虑到节省系统资源,只创建了两个线程分别实现服务端的收发数据。下面直接上代码,该代码为在PC机上程序,已作详细注释。 server.c #include #include #include #include #include #include #include #incl
  • TCP线程出现非正常断开的解决方法

    千次阅读 2011-08-18 19:06:50
    在多线程任务中,TCP任务通过三次握手能建立可靠的连接,但是经常会发生在数据传输或通信时发生网络突然断开或者长时间连接空循环监听而未进行操作,需要在软件设计时考虑程序运行中检测到服务器对客户端的这一“虚...
  • 在工控等领域,后台线程要始终保持网络处于连接状态,这是,就需要处理好当网络异常断开后,如何及何时重连的问题;
  • 线程网络通信

    千次阅读 2011-10-09 20:08:46
    最近写一个多线程网络通信DLL,原来认为自己的网络通信这一方面水平即使不是杠杠滴,也得当当滴,至不成也得忽忽滴。结果真得一写起来,发现很多东西都吃不透,都懂,都明白大其概,但真正应用哪种更好,哪种更...
  • 在多线程编程中其中使用一个线程来accept要连接的客户端。同时在接受client的...如果在发送过程中出现任何一个client端的断线,则整个程序都会退出。 ssize_t send(int sockfd, const void *buff, size_t nbytes...
  • 我在运行过一个网上下载的多线程服务器后,我自己写的单线程的客户端和服务端就不再连的上了, 我百度了一下说是可能是因为我多次调用了connectToHost,所以点击连接时程序会异常退出,但这个问题怎么解决呢?...
  • linux网络编程之简单的服务器多线程

    千次阅读 2016-07-26 18:12:26
    最近两天了linux的网络编程,自己写了一个demo,熟悉socket的几个主要API的用法: 虚拟机下的ubuntu 14.04 OS,程序包括: 客户端:发送连接请求;一旦连接建立,将用户输入的信息发送给服务器;输入end,客户端程序...
  • 本文详细介绍了c socket编程的原理和实现步骤,包括tcp和udp,其中考虑到tcp的面向连接的特性,使用了多线程编程的技术。供大家参考。
  • 网络异常断开原因主要有那些呢?归纳起来主要有以下两种: 1、客户端程序异常。  对于这种情况,我们很好处理,因为客户端程序异常退出会在服务端引发ConnectionReset的Socket异常(就是WinSock2中的10054异常...
  • 具备多线程 2. 监听某个端口 3. 连接远程服务器 4. 保存并管理所有链接,外部与网络库操作通过链接ID 5. 向某个连接发送数据 6. 强制关闭某个链接 7. 网络事件回掉:connect, receive, close 8. 错误处理 网络库...
  • Windows系统PC机和自动化设备之间的TCP通信,使用的是WinSocket,不使用心跳包之类的,在非UI线程中, 不能使用WSAAsyncSelect()函数绑定消息机制,如何判断对方连接断线,如网线断开, 或者对方程序退出
  • 网络socket编程实现并发服务器——多线程编程

    万次阅读 多人点赞 2019-04-05 00:20:19
    线程编程

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,644
精华内容 12,657
关键字:

网络断开退出线程