带有线程和服务的Python套接字服务器无法接受来自客户端的连接

时间:2014-03-21 23:28:34

标签: python sockets service socketserver

我正在制作一个将连接到Arduino的计费引擎,这样可以使用python套接字和带有以太网屏蔽的Arduino进行通信,但是当我尝试更改服务器时,在python中进行服务,套接字失败接受来自客户端的连接

import win32service
import win32serviceutil
import win32api
import win32con
import win32event
import win32evtlogutil


import os, sys, string, time

# TCP Chat Server
import socket, select

import mysql.connector
from mysql.connector import errorcode

import logging

import threading

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('C:\server.log')
logger.addHandler(fh)

service_status = False

class BillingThread(threading.Thread):
    """docstring for BillingThread"""

    def __init__(self, service_status):
        threading.Thread.__init__(self)

        config = {
            'user': 'root',
            'password': '',
            'host': 'localhost',
            'database': 'billing',
            'raise_on_warnings': True,
        }

        try:
            logger.error("Connecting Database")
            self.condb = mysql.connector.connect(**config)
            logger.error("Database Connected")
        except mysql.connector.Error as err:
            if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
                print("Something is wrong with your user name or password")
                logger.error("Database: Username or Password is wrong")
            elif err.errno == errorcode.ER_BAD_DB_ERROR:
                print("Database does not exists")
                logger.error("Database does not exists")
            else:
                print(err)
                logger.error(err)

        self.service_status = service_status

    def setStop(self):
        self.service_status = False

    def run(self):
        # List to keep track of socket descriptors
        CONNECTION_LIST = []
        RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2
        PORT = 50000

        server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # this has no effect, why ?
        server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        server_socket.bind(("0.0.0.0", PORT))
        server_socket.listen(10)
        server_socket.settimeout(2)

        # Add server socket to the list of readable connections
        CONNECTION_LIST.append(server_socket)

        logger.error("server started with Port %s" % (PORT))


        logger.error(self.service_status)
        while self.service_status==True:
            logger.error("Waiting Client")
            logger.error( CONNECTION_LIST )
            read_sockets, write_sockets, error_sockets = select.select(CONNECTION_LIST, [], [], 2)

            for sock in read_sockets:
                #New connection
                if sock == server_socket:
                    logger.error("Accepting Client...")
                    # Handle the case in which there is a new connection recieved through server_socket
                    sockfd, addr = server_socket.accept()
                    CONNECTION_LIST.append(sockfd)
                    logger.error("Client %s Accepted" % (addr))
                    #print "Client (%s, %s) connected" % addr

                #Some incoming message from a client
                else:
                    # Data recieved from client, process it
                    try:
                        #In Windows, sometimes when a TCP program closes abruptly,
                        # a "Connection reset by peer" exception will be thrown
                        data = sock.recv(RECV_BUFFER)
                        logger.error("Recieved Message: %s" % (data))
                        """
                        if data:
                            #AT+GETACCESS=cardID,pin
                            #AT+GETBALANCE=cardID
                            #AT+ADDCARD=cardID
                            curpos = data.find('=')
                            cmd = data[:curpos]
                            data = data[(curpos+1):]

                            if cmd == 'AT+GETACCESS':
                                (cardId, pin) = data.split(',')
                                status = self.checkID(cardId, pin)
                                saldo = self.getBalance(cardId)
                                if status:
                                    sock.send("AT+STATUS=OK,%s" % (saldo))
                                else:
                                    sock.send("AT+STATUS=CANCEL")
                            elif cmd == 'AT+GETBALANCE':
                                saldo = self.getSaldo(data)
                                sock.send("AT+BALANCE=%s" % (saldo))
                            elif cmd == 'AT+ADDCARD':
                                self.addCard(data)
                                sock.send("AT+STATUS=OK,0")
                        """ 
                    except:
                        #print "Client (%s, %s) is offline" % addr
                        sock.close()
                        CONNECTION_LIST.remove(sock)
                        logger.error("Client: %s is Offline" % (addr))
                        continue

        server_socket.close


    def addCard(self, cardId):
        logger.error("Adding New Card")
        cursor = self.condb.cursor()
        sql = "INSERT INTO `card` (`card_id`) VALUES (`card_id`)" % (cardId)
        cursor.execute(sql)
        self.condb.commit()
        cursor.close()
        logger.error("New Card Added")

    def checkID(self, cardId, pin):
        logger.error("Check ID: %s, %s" % (cardId, pin))
        cursor = self.condb.cursor()
        sql = "SELECT * FROM `member` WHERE `card_id`='%s' AND `pin`='%s'" % (cardId, pin)
        cursor.execute(sql)
        row = cursor.fetchone()
        if cursor.rowcount > 0:
            ret = True
        else:
            ret = False
        # self.condb.commit()
        cursor.close()
        return ret

    def getBalance(self, cardId):
        logger.error("Get Balance: %s" % (cardId))
        balance = 0
        cursor = self.condb.cursor()
        sql = "SELECT * FROM `balance` WHERE `card_id`='%s'" % (cardId)
        cursor.execute(sql)
        row = cursor.fetchone()
        while row is not None:
            balance = row['balance']
        # self.condb.commit()
        cursor.close()
        return balance




class aservice(win32serviceutil.ServiceFramework):

    _svc_name_ = "Service Billing Mesin Cuci"
    _svc_display_name_ = "Service Billing Mesin Cuci"
    _svc_description_ = "Service Billing untuk akses pemakaian mesin cuci"

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)  


    def SvcStop(self):
        #thread.exit()
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        #self.ReportServiceStatus(win32service.SERVICE_STOPPED)
        win32event.SetEvent(self.hWaitStop)                    

    def SvcDoRun(self):
        import servicemanager      
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))

         #self.timeout = 640000    #640 seconds / 10 minutes (value is in milliseconds)
        self.timeout = 500    #5 seconds
        # This is how long the service will wait to run / refresh itself (see script below)
        service_status = True 
        serverthread = BillingThread(service_status)
        serverthread.start()

        while 1:
            # Wait for service stop signal, if I timeout, loop again
            rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout)
            # Check to see if self.hWaitStop happened
            if rc == win32event.WAIT_OBJECT_0:
                # Stop signal encountered
                service_status = False
                serverthread.setStop()
                servicemanager.LogInfoMsg("Service Billing Mesin Cuci - STOPPED!")  #For Event Log
                logger.error("Service Stopped")
                break
            else:
                pass





def ctrlHandler(ctrlType):
    return True

if __name__ == '__main__':  
    win32api.SetConsoleCtrlHandler(ctrlHandler, True)  
    win32serviceutil.HandleCommandLine(aservice)

此客户端代码使用Arduino

#include <SoftwareSerial.h>
#include <SPI.h>
#include <Ethernet.h>
//#include <SD.h>
//#include <Timer.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,111);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255, 255, 255, 0);
// Enter the IP address of the server you're connecting to:
IPAddress server(192,168,1,1); 

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 23 is default for telnet;
// if you're using Processing's ChatServer, use  port 10002):
EthernetClient client;

boolean alreadyConnected = false; // whether or not the client was connected previously

char cmd[25];
char replay[255];

int i=0;
boolean cmdstatus=false;

/**
 * RFID
 */
#define rxPin 6
#define txPin 7

SoftwareSerial SerialRFID(rxPin, txPin);

char get_readID[] = { 0xAA , 0x00, 0x03, 0x25, 0x26, 0x00, 0x00, 0xBB };
//-- End RFID

#define relayPin 3

//File myFile;  //SDCard

//Timer t;  //Timer

boolean pulseCheck = false;

SoftwareSerial mySerial(3, 5); // RX, TX

void setup() {

  // start the Ethernet connection:
  //if (Ethernet.begin(mac) == 0) {
    //Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip, gateway, subnet);

  //}

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  mySerial.begin(9600);
  Serial.print("Machine address:");
  Serial.println(Ethernet.localIP());
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 50000))
    Serial.println("connected");
  else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }

  //pinMode(relayPin, OUTPUT);
  //digitalWrite(relayPin, LOW);
  //digitalWrite(relayPin, HIGH);

  //Serial.println("Initializing SD card...");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  /*myFile = SD.open("test.txt", FILE_WRITE);

  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  // re-open the file for reading:
  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");

    // read from the file until there's nothing else in it:
    while (myFile.available()) {
        Serial.write(myFile.read());
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }*/


  //t.pulse(pin, 60 * 60 * 1000, HIGH); // 60 minutes or 1 hour 

   SerialRFID.begin(9600);
   Serial.println("RFID Reader is Ready...");

   mySerial.begin(9600);
   mySerial.listen();
}

void loop()
{
  cmdstatus = false;

  if (client.available() > 0) {
    // read the bytes incoming from the client:
    while(client.available() && i<25) {
        Serial.println(cmd[i]);
        cmd[i] = client.read();
        if ( cmd[i] == '\n' ) {
          cmd[i--] = '\0';
          //mySerial.write(cmd);
          Serial.print(cmd);
          //Serial.println();
          i=0;
          for(i=0; i<25; i++)
            cmd[i] = '\0';

          i=-1;
          cmdstatus = true;
        }
        i++;
      }
  }


  int j = 0;

  mySerial.listen();
  delay(200); //allows all serial sent to be received together
  if (mySerial.available() > 0) {
    delay(50); //allows all serial sent to be received together
    while(mySerial.available() > 0 && j<25) {
      replay[j++] = mySerial.read();
    }
    replay[j++]='\0';

    mySerial.write("AT+OK");
    delay(200); //allows all serial sent to be received together
    mySerial.write("AT+OK");
    delay(200); //allows all serial sent to be received together
    mySerial.write("AT+OK");
    delay(200); //allows all serial sent to be received together

    Serial.println(replay);
    if(j>0) {
      String cmd = "";
      int icmd = 0;
      for(icmd=0; icmd<String(replay).length(); icmd++) {
        cmd += replay[icmd];
        if (replay[icmd] == '=') {
          break;
        }
      }

      if (cmd.equals("AT+CARDREQ=")) {
        String pin_replay = "";
        int ipin = 0;
        for (ipin=cmd.length(); ipin<String(replay).length(); ipin++) {
          pin_replay += replay[ipin];
        }
        Serial.println(pin_replay);
        pulseCheck = true;

      }

      j=0;
      for(j=0; j<25; j++)
        replay[j] = '\0';
     } 
  }

  SerialRFID.listen();
  delay(200);
  String id = getID(50);
  if ( id != "" ) {
    Serial.println("RFID CARD is "+id+">");  

    if (pulseCheck == true) {
      mySerial.write("AT+MSG=Silakan\nTunggu...");
      pulseCheck = false;
    } else {
      mySerial.write("AT+PINREQ");
    }
  }

}

String decToHex(byte decValue, byte desiredStringLength) {

  String hexString = String(decValue, HEX);
  while (hexString.length() < desiredStringLength) hexString = "0" + hexString;

  hexString.toUpperCase();

  return hexString;
}

String getID(int Delay) {
  int counter = 0;
  for (counter =0 ; counter < 8 ; counter++){
    SerialRFID.write(get_readID[counter]);
  }

  delay(Delay);

  String rf_output = "";

  while(SerialRFID.available()>0)
    rf_output = rf_output + decToHex( SerialRFID.read(), 2 );

  if ( rf_output != "" && rf_output.length() > 14 && rf_output != "AA0002018380BB" )
    return rf_output;
  else
    return "";
}

此代码没有线程和服务

import socket, select

import logging

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('out.log')
logger.addHandler(fh)

logger.error("OUTSIDE")

#Function to broadcast chat messages to all connected clients
def broadcast_data(sock, message):
    #Do not send the message to master socket and the client who has send us the message
    for socket in CONNECTION_LIST:
        if socket != server_socket and socket != sock:
            try:
                socket.send(message)
            except :
                # broken socket connection may be, chat client pressed ctrl+c for example
                socket.close()
                CONNECTION_LIST.remove(socket)

if __name__ == '__main__':

    # List to keep track of socket descriptors
    CONNECTION_LIST = []
    RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2
    PORT = 50000

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # this has no effect, why ?
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server_socket.bind(("0.0.0.0", PORT))
    server_socket.listen(10)
    server_socket.settimeout(2)

    logger.error("START SERVER")

    # Add server socket to the list of readable connections
    CONNECTION_LIST.append(server_socket)

    print "Chat server started on port " + str(PORT)

    while 1:
        print "Waiting Client"
        print CONNECTION_LIST
        # Get the list sockets which are ready to be read through select
        read_sockets, write_sockets, error_sockets = select.select(CONNECTION_LIST, [], [], 2)
        print read_sockets
        for sock in read_sockets:
            #New connection
            if sock == server_socket:
                # Handle the case in which there is a new connection recieved through server_socket
                sockfd, addr = server_socket.accept()
                CONNECTION_LIST.append(sockfd)
                print "Client (%s, %s) connected" % addr
                logger.error("Client (%s, %s) connected" % addr)

                broadcast_data(sockfd, "[%s:%s] entered room\n" % addr)
            #Some incoming message from a client
            else:
                # Data recieved from client, process it
                try:
                    #In Windows, sometimes when a TCP program closes abruptly,
                    # a "Connection reset by peer" exception will be thrown
                    data = sock.recv(RECV_BUFFER)
                    if data:
                        broadcast_data(sock, "\r" + '<' + str(sock.getpeername()) + '> ' + data)

                except:
                    broadcast_data(sock, "Client (%s, %s) is offline" % addr)
                    print "Client (%s, %s) is offline" % addr
                    logger.error("Client (%s, %s) is offline" % addr)
                    sock.close()
                    CONNECTION_LIST.remove(sock)
                    continue


    server_socket.close

0 个答案:

没有答案
相关问题