我正在制作一个将连接到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