本實驗為了實現PHP 和Servlet 進行通信,費了不少周折。。。。。。。。而且網上現成的資料都不完整,懷著激動的心情將本實驗遇到的錯誤和解決方法和大家分享:
PHP 作為Client端,Servlet 作為Server 端
在Server端,一般的做法是:
1. 寫一個Servlet 類,並將該Servlet 設置為服務器啟動時就加載的類。
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>Servlet.LoginServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
2. 如果單獨在該Servelt的init() 方法中編寫Server端代碼,並進行監聽
while(true){
socket = server.accept();
}
則會造成Tomcat 啟動超時。
正確的做法應該是單獨寫一個 監聽處理線程類SocketServer ,然後再init() 中,用多線程的方式來啟動該線程:
public void init(ServletConfig config){
new Thread(){
public void run(){
try{
ServerSocket server =new ServerSocket(4700);
Socket socket = null;
while(true){
socket=server.accept();
SocketServer sServer=new SocketServer(socket);
sServer.start();
}
}catch(IOException e){
System.out.println(e.getMessage());}
}
}.start();
}
public class SocketServer extends Thread{
private Socket socket;
public SocketServer(Socket socket){
this.socket = socket;
}
public void run(){
String output = "";
try {
BufferedReader is=new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter os=new PrintWriter(socket.getOutputStream());
String line = null;
line = is.readLine();
System.out.println(line);
output = "server send";
os.println(output);
os.flush();
is.close();
os.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
曾經一度在Client端,接收不到Server端發送過去的數據,認真檢查了下代碼,發現沒有os.flush();
通過在init() 方法中,起一個新的線程,然後通過這個新的線程對每一個請求啟動一個新線程來響應來自Client 端的Socket請求
在Client端,采用PHP編寫,
Client端先發送數據給Server端,然後接收Server端的返回數據,進行顯示
$userName = 'veverrr';
$password = 'SWJTU';
$write_str = '';
if ($userName == null || $password == null){
// 跳轉回登錄系統
}
$socket_host ='localhost';
$socket_port = 4700;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$connection = socket_connect($socket, $socket_host,$socket_port);
$write_str .= $userName.$password.chr(13) . chr(10);
if (!socket_write($socket, $write_str,strlen($write_str))){
echo "connect write";
}
$return_str = socket_read($socket, 1024);
echo $return_str;
socket_close($socket);
Server在使用is.readline() 時,就直接卡住了,後來在外文網站上找到了方法,一試驗就通過了。
主要是在Client端發送的數據後面加上 chr(13).chr(10) 表示先回車再換行,將其轉換成java能夠識別的格式。
PHP 和Servlet 通信的全部過程和注意點就那麼多了。
摘自 veverrr的專欄