我一直在尝试编写PHP脚本,以通过连接到服务器计算机的GSM调制解调器发送SMS消息。
下面是上述PHP脚本。
<?php
$device = "COM7";
exec("mode $device BAUD=9600 PARITY=n DATA=8");
$comport = fopen($device, "w");
fputs($comport,"AT+CMGF=1\n\r");
fputs($comport,"AT+cmgs=\"xxxxxxxxxx\"\n\r");
fputs($comport,"sms text\n\r");
fputs($comport,chr(26));
fclose($comport);
echo "done";
?>
当我尝试运行以上代码时,出现以下错误;
警告:fopen(COM7):无法打开流:权限被拒绝 第4行的E:\ wamp \ www \ sms \ index.php
和
警告:fclose()期望参数1为资源,布尔值在 第9行的E:\ wamp \ www \ sms \ index.php
我尝试更改Windows中的用户权限,以允许WAMP服务器完全访问,默认情况下该WAMP服务器已经拥有。
作为一种解决方法,我尝试使用DIO扩展名,该扩展名在尝试打开端口时给出了类似的错误。 DIO还给出了拒绝权限错误。
在这里建议在stackoverflow中使用GSM调制解调器的物理地址而不是“ COM7”,我尝试过不起作用。另一个答案是建议将www数据添加到拨出组中,但是该解决方案是针对Linux的。
我尝试编写Java servlet作为解决此问题的方法。 Java程序作为独立文件运行,但是当它通过Tomcat作为servlet运行时,它再次出现“访问冲突”错误。我将RXTX库用于Java servlet。
所以我猜想这个错误是由于分配给尝试通过服务器访问com端口的人的权限不足引起的。 (当我从上述PHP脚本中运行echo get_current_user();
时得到了“ SYSTEM”)
我正在尝试查找此错误的根本原因。非常感谢您的帮助。
下面是使用RXTX库的Java SMS发送方类。
import java.io.*;
import java.util.*;
import gnu.io.*;
public class SMSsender {
static Enumeration portList;
static CommPortIdentifier portId;
static String messageString1 = "AT";
static String messageString3 = "AT+CMGF=1";
static String messageString4 = "AT+CMGS=\"+xxxxxxxxxx\"";
static String messageString5 = "TESTY2";
static SerialPort serialPort;
static OutputStream outputStream;
static InputStream inputStream;
static char enter = 13;
static char CTRLZ = 26;
public void sendMessage(String[] args) throws InterruptedException {
portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements()) {
portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
if (portId.getName().equals("COM7")) {
try {
serialPort = (SerialPort) portId.open("COM7", 2000);
} catch (PortInUseException e) {
System.out.println("err");
}
try {
outputStream = serialPort.getOutputStream();
inputStream = serialPort.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,
SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
}
try {
outputStream.write((messageString1 + enter).getBytes());
Thread.sleep(100);
outputStream.flush();
// outputStream.write((messageString2 + enter).getBytes());
Thread.sleep(100);
outputStream.flush();
outputStream.write((messageString3 + enter).getBytes());
Thread.sleep(100);
outputStream.flush();
outputStream.write((messageString4 + enter).getBytes());
Thread.sleep(100);
outputStream.flush();
outputStream.write((messageString5 + CTRLZ).getBytes());
outputStream.flush();
Thread.sleep(100);
System.out.println("step 1");
Thread.sleep(3000);
outputStream.close();
serialPort.close();
System.out.println("step 2");
} catch (IOException e) {
e.printStackTrace();
serialPort.close();
} finally {
serialPort.close();
}
}
}
}
}
}
以上代码在作为独立应用程序在服务器外部运行时有效。
以下是Servlet代码,该代码调用上述类以发送SMS。
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class sendSMS extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// Set the response MIME type of the response message
response.setContentType("text/html");
// Allocate a output writer to write the response message into the network socket
PrintWriter out = response.getWriter();
SMSsender obj = new SMSsender();
try {
obj.sendMessage(null);
}
catch(Exception e)
{
out.println(e.getMessage());
}
finally {
out.close(); // Always close the output writer
}
}
}
当该servlet通过Apache Tomcat运行时,服务器会自动关闭,并在日志中显示以下错误。
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000001cf32174465, pid=5828, tid=2276
#
# JRE version: Java(TM) SE Runtime Environment (10.0.2+13) (build 10.0.2+13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0.2+13, mixed mode, tiered, compressed oops, g1 gc, windows-amd64)
# Problematic frame:
# C [rxtxSerial.dll+0x4465]
#
# No core dump will be written. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
答案 0 :(得分:1)
我能够解决问题。
显然,Windows不再允许通过虚拟文件名与串行端口通信。对于PHP,我试图通过fopen("com7")
与com端口取得联系。因此,这种方法似乎不再可行。这是根据David Gibson的说法。 View Source Here。如果可以找到原始资源,我很乐意阅读更多内容。
根据David Gibson的帖子,像DIO这样的PHP扩展在Windows环境中不是很稳定。因此,我停止尝试为我的PHP代码找到解决方案。
Java解决方法
之前,我尝试使用RXTX Java库。尽管该代码可以作为独立应用程序使用,但是通过tomcat运行时,它失败并显示“访问冲突”错误。 我想知道RXTX是否仍在积极开发中。
无论如何,我都对平台独立解决方案jSerialComm感到厌倦。令人惊讶的是,它不需要任何DLL或任何其他本机库。
有了这个很棒,易于使用的库,我终于能够通过servlet发送SMS。我在下面发布了我的有效Java代码,以供您参考。
我希望这会对遇到相同问题的人有所帮助!干杯!
感谢Mehdi,Erwin和Sanguinary为使用这个惊人的Stackoverflow平台所提供的指导,当然也感谢开发人员!
注意:下面的这段代码很杂乱,没有经过优化。此代码仅供参考。
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
//import java.io.InputStream;
import java.util.Scanner;
import com.fazecast.jSerialComm.*;
public class sendSMS extends HttpServlet {
SerialPort ubxPort;
static String messageString1 = "AT";
static String messageString2 = "AT+CMGF=1";
static String messageString3 = "AT+CMGS=\"+xxxxxxxxxx\"";
static String messageString4 = "TESTY2";
static char enter = 13;
static char CTRLZ = 26;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
// Set the response MIME type of the response message
response.setContentType("text/html");
// Allocate a output writer to write the response message into the network socket
PrintWriter out = response.getWriter();
try {
ubxPort = SerialPort.getCommPort("com7");
boolean openedSuccessfully = ubxPort.openPort();
out.println("h1<br>");
if(openedSuccessfully)
{
out.println("Port Opened<br>");
byte[] buffer = (messageString1 + enter).getBytes();
ubxPort.writeBytes(buffer, buffer.length);
out.println("1 sent<br>");
InputStream in = ubxPort.getInputStream();
try
{
for (int j = 0; j < 1000; ++j)
System.out.print((char)in.read());
in.close();
} catch (Exception e) { e.printStackTrace(); }
buffer = (messageString2 + enter).getBytes();
ubxPort.writeBytes(buffer, buffer.length);
out.println("2 sent<br>");
try
{
for (int j = 0; j < 1000; ++j)
System.out.print((char)in.read());
in.close();
} catch (Exception e) { e.printStackTrace(); }
buffer = (messageString3 + enter).getBytes();
ubxPort.writeBytes(buffer, buffer.length);
out.println("3 sent<br>");
try
{
for (int j = 0; j < 1000; ++j)
System.out.print((char)in.read());
in.close();
} catch (Exception e) { e.printStackTrace(); }
buffer = (messageString4 + CTRLZ).getBytes();
ubxPort.writeBytes(buffer, buffer.length);
out.println("4 sent<br>");
try
{
for (int j = 0; j < 1000; ++j)
System.out.print((char)in.read());
in.close();
} catch (Exception e) { e.printStackTrace(); }
}
}
catch(Exception e)
{
out.println("here3");
out.println(e.getMessage());
}
finally {
ubxPort.closePort();
out.println("here4");
out.close(); // Always close the output writer
}
}
}