0

I'm making a billing engine that will be connected to the Arduino, so that can communicate with each other using python socket and the Arduino with ethernet shield, but when I try to change the server is made in python into service, the socket failed accepts connections from client

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)

This Client Code using 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 "";
}

This Code without Thread and Service

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
tshepang
  • 12,111
  • 21
  • 91
  • 136
dnaextrim
  • 1
  • 2
  • Can you attach the client source code also? Might be that there is an issue, or the network issue. You are running the server on the PC and the client on Arduino? Are they on the same network? Can you ping the PC from Arduino? – bosnjak Mar 21 '14 at 23:35
  • Yes, I use arduino as client and arduino can ping from the pc – dnaextrim Mar 21 '14 at 23:55
  • What does the Arduino serial output say? Does this line get executed ever: `Serial.println("connected");`? – bosnjak Mar 22 '14 at 00:05
  • if i run server without thread and windows service arduino say "connected", and the server say "Client (192.168.1.111, 1025) connected", but if i run server with thread and windows service arduino say "connection failed" and server no say anything(can read client connections) – dnaextrim Mar 22 '14 at 01:11
  • Change `except:` to `except socket.error:` and undo the change. Then you will recognize an other error that should not be caught. Why don't you use `import SocketServer`? – User Mar 22 '14 at 16:55
  • I've found the problem, localhost connections will be accepted, but if the connection is coming from outside do not get, so I seem to matter on the firewall, after I turn off the firewall, Arduino finally managed to connect to the server – dnaextrim Mar 22 '14 at 22:32

0 Answers0