JAVA也不例外,物件程式導向的程式語言,筆者對此一直還懵懵懂懂,但透過撰寫這個程式,對於類別架構、Socket還有AWT(Abstract Window Toolkit)物件的應用,更有不同的心得。
首先,撰寫Socket程式,由於是利用TCP傳輸的server/client架構來撰寫,應用在AWT視窗程式上,就必須要透過多執行緒來執行。總不能在server等待連線的時候,把所有的資源佔住,讓其他視窗的物件無法執行吧。
因此程式架構的設計上,利用兩個執行緒來跑socket的兩個port,一個用來send文字,另外一個用來receive文字,達到雙向傳輸的功能。且利用執行緒就可以同時還讓視窗的其他物件可以有事件監聽,譬如button可以設計一個exit鍵,按下之後把視窗給關閉,架構圖如下:
JAVA是一個物件導向的語言,所以常常會看到new {Object()}這類的語法,可以想像成整個JAVA就是一個書桌,而這些物件就是你擺在書桌上面的鉛筆、橡皮擦還有書籍,可以為這些物件設計功能事件,譬如:橡皮擦會在書本髒掉時做擦拭清潔。整個合起來就是一個AWT的視窗程式了。
範例中使用了Frame、Button、Lable、TextArea、TextField和自己創造的類別CServer的物件,利用new的語法創造並且使用constructor的方式指定物件的預設架構。
static Frame frm=new Frame("JAVA Socket Server AWT Program");
static Button btn1=new Button("Start");
static Button btn2=new Button("Exit");
static Label lab1=new Label("Host IP Address");
static Label title=new Label("JSocket");
static TextArea txa1=new TextArea("",6,10,TextArea.SCROLLBARS_VERTICAL_ONLY);
static TextArea txa2=new TextArea("",6,10,TextArea.SCROLLBARS_NONE);
static TextField txf1=new TextField("127.0.0.1");
static CServer_send ss=new CServer_send();
static CServer_Recv sr=new CServer_Recv();
接著利用setBound以及add method,把一連串的物件Layout建立好。然後設計button的事件,當btn1按下之後,產生兩個thread分別跑socket的兩個port,用來傳輸及接收文字;btn2則是用來作為程式離開的事件使用。事件actionPerformed則實作ActionListener介面,當按下的button為btn1時,則跑繼承了thread的CServer類別的執行緒;如果是btn2則是關閉整個frm視窗。
btn1.addActionListener(new ActLis());
btn2.addActionListener(new ActLis());
static class ActLis implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Button btn=(Button) e.getSource();
if(btn==btn1)
{
txa1.setText("Waiting for connecting("+txf1.getText()+")...\n");
System.out.println("Waiting for connecting...");
txf1.setEditable(false);
ss.start();
sr.start();
}
else if(btn==btn2)
System.exit(0);
else
System.out.println("No Button Click!");
}
}
執行緒的執行上,JAVA的設計是,建立繼承了Thread的類別,在run()的method中放入要利用多執行緒執行的程式碼,在其他類別中就可以利用呼叫start()這個method來啟動執行緒。像是底下,利用繼承了Thread的CServer_send類別產生ss的物件,在主類別test_server中就可以利用ss.start()來呼叫CServer_send中的run()來執行。
class CServer_send extends Thread
{
static int flag_send=0;
public void run()
{
try
{
test_server.txa2.addKeyListener(new KeyLis());
ServerSocket svs = new ServerSocket(2525);
Socket s=svs.accept();
test_server.txa1.append("Clinet connecting for sending successfully!!\n");
System.out.println("Clinet connecting for sending successfully!!");
System.out.println("Data transfering...");
OutputStream out=s.getOutputStream();
String str;
while(true)
{
if(flag_send==1)
{
str=test_server.txa2.getText();
out.write(str.getBytes());
flag_send=0;
System.out.print("Send:"+str);
}
sleep((int)(100*Math.random()));
}
//in.close();
//out.close();
//s.close();
}
catch(Exception e)
{
System.out.println("Error:"+e);
}
}
static class KeyLis extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
flag_send=1;
}
}
public void keyReleased(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
test_server.txa1.append("Server: "+test_server.txa2.getText());
test_server.txa2.setText("\r");
}
}
}
}
public class test_server
{
public static void main (String[] args)
{
static CServer_send ss=new CServer_send();
ss.start();
}
}
透過以上就可以很簡單地把JAVA AWT Socket的網路文字傳輸程式給實做出來了。底下為參考程式碼:
test_server.java
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class CServer_send extends Thread
{
static int flag_send=0;
public void run()
{
try
{
test_server.txa2.addKeyListener(new KeyLis());
ServerSocket svs = new ServerSocket(2525);
Socket s=svs.accept();
test_server.txa1.append("Clinet connecting for sending successfully!!\n");
System.out.println("Clinet connecting for sending successfully!!");
System.out.println("Data transfering...");
OutputStream out=s.getOutputStream();
String str;
while(true)
{
if(flag_send==1)
{
str=test_server.txa2.getText();
out.write(str.getBytes());
flag_send=0;
System.out.print("Send:"+str);
}
sleep((int)(100*Math.random()));
}
//in.close();
//out.close();
//s.close();
}
catch(Exception e)
{
System.out.println("Error:"+e);
}
}
static class KeyLis extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
flag_send=1;
}
}
public void keyReleased(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
test_server.txa1.append("Server: "+test_server.txa2.getText());
test_server.txa2.setText("\r");
}
}
}
}
class CServer_Recv extends Thread
{
public void run()
{
byte buff[] = new byte[1024];
try
{
ServerSocket svs = new ServerSocket(2526);
Socket s=svs.accept();
test_server.txa1.append("Clinet connecting for receiving successfully!!\n");
System.out.println("Clinet connecting for receiving successfully!!");
InputStream in=s.getInputStream();
int n;
while(true)
{
n=in.read(buff);
test_server.txa1.append("Client: "+new String(buff,0,n));
System.out.print("Received from client: ");
System.out.print(new String(buff,0,n));
sleep((int)(100*Math.random()));
}
//in.close();
//s.close();
}
catch(Exception e)
{
System.out.println("Error:"+e);
}
}
}
public class test_server
{
static Frame frm=new Frame("JAVA Socket Server AWT Program");
static Button btn1=new Button("Start");
static Button btn2=new Button("Exit");
static Label lab1=new Label("Host IP Address");
static Label title=new Label("JSocket");
static TextArea txa1=new TextArea("",6,10,TextArea.SCROLLBARS_VERTICAL_ONLY);
static TextArea txa2=new TextArea("",6,10,TextArea.SCROLLBARS_NONE);
static TextField txf1=new TextField("127.0.0.1");
static CServer_send ss=new CServer_send();
static CServer_Recv sr=new CServer_Recv();
public static void main (String[] args)
{
try
{
InetAddress adr=InetAddress.getLocalHost();
txf1.setText(adr.getHostAddress());
btn1.addActionListener(new ActLis());
btn2.addActionListener(new ActLis());
frm.addWindowListener(new WinLis());
frm.setLayout(null);
title.setBounds(20,40,75,40);
btn1.setBounds(280,40,100,20);
btn2.setBounds(280,65,100,20);
frm.setBounds(100,100,400,300);
frm.setBackground(new Color(151,255,255));
lab1.setBounds(100,40,160,20);
txa1.setBounds(20,95,360,140);
txa2.setBounds(20,240,360,40);
txf1.setBounds(100,65,160,20);
txa1.setEditable(false);
title.setFont(new Font("Serief",Font.BOLD+Font.ITALIC,18));
title.setForeground(Color.BLUE);
frm.add(title);
frm.add(btn1);frm.add(btn2);
frm.add(lab1);
frm.add(txa1);frm.add(txa2);
frm.add(txf1);
frm.setVisible(true);
}
catch(Exception e)
{
System.out.println("Error:"+e);
}
}
static class ActLis implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Button btn=(Button) e.getSource();
if(btn==btn1)
{
txa1.setText("Waiting for connecting("+txf1.getText()+")...\n");
System.out.println("Waiting for connecting...");
txf1.setEditable(false);
ss.start();
sr.start();
}
else if(btn==btn2)
System.exit(0);
else
System.out.println("No Button Click!");
}
}
static class WinLis extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
frm.dispose();
System.exit(0);
}
}
}
test_client.java
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class CClient_send extends Thread
{
static int flag_send=0;
public void run()
{
try
{
test_client.txa2.addKeyListener(new KeyLis());
Socket s=new Socket(test_client.txf1.getText(),2526);
test_client.txa1.append("Connected with server for sending successfully!!\n");
System.out.println("Connected with server for sending successfully!!");
System.out.println("Data transfering...");
OutputStream out=s.getOutputStream();
String str;
while(true)
{
if(flag_send==1)
{
str=test_client.txa2.getText();
out.write(str.getBytes());
flag_send=0;
System.out.print("Send:"+str);
}
sleep((int)(100*Math.random()));
}
//in.close();
//out.close();
//s.close();
}
catch(Exception e)
{
System.out.println("Error:"+e);
}
}
static class KeyLis extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
flag_send=1;
}
}
public void keyReleased(KeyEvent e)
{
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
test_client.txa1.append("Client: "+test_client.txa2.getText());
test_client.txa2.setText("\r");
}
}
}
}
class CClient_Recv extends Thread
{
public void run()
{
byte buff[] = new byte[1024];
try
{
Socket s=new Socket(test_client.txf1.getText(),2525);
test_client.txa1.append("Connected with server for receiving successfully!!\n");
System.out.println("Connected with server for receiving successfully!!");
InputStream in=s.getInputStream();
int n;
while(true)
{
n=in.read(buff);
test_client.txa1.append("Server: "+new String(buff,0,n));
System.out.print("Received from server: ");
System.out.print(new String(buff,0,n));
sleep((int)(100*Math.random()));
}
//in.close();
//s.close();
}
catch(Exception e)
{
System.out.println("Error:"+e);
}
}
}
public class test_client
{
static Frame frm=new Frame("JAVA Socket Client AWT Program");
static Button btn1=new Button("Connect");
static Button btn2=new Button("Exit");
static Label lab1=new Label("Server IP Address");
static Label title=new Label("JSocket");
static TextArea txa1=new TextArea("",6,10,TextArea.SCROLLBARS_VERTICAL_ONLY);
static TextArea txa2=new TextArea("",6,10,TextArea.SCROLLBARS_NONE);
static TextField txf1=new TextField("127.0.0.1");
static CClient_Recv cr=new CClient_Recv();
static CClient_send cs=new CClient_send();
public static void main (String[] args)
{
try
{
btn1.addActionListener(new ActLis());
btn2.addActionListener(new ActLis());
frm.addWindowListener(new WinLis());
frm.setLayout(null);
title.setBounds(20,40,75,40);
btn1.setBounds(280,40,100,20);
btn2.setBounds(280,65,100,20);
frm.setBounds(450,150,400,300);
frm.setBackground(new Color(151,255,255));
lab1.setBounds(100,40,160,20);
txa1.setBounds(20,95,360,140);
txa2.setBounds(20,240,360,40);
txf1.setBounds(100,65,160,20);
txa1.setEditable(false);
title.setFont(new Font("Serief",Font.BOLD+Font.ITALIC,18));
title.setForeground(Color.BLUE);
frm.add(title);
frm.add(btn1);frm.add(btn2);
frm.add(lab1);
frm.add(txa1);frm.add(txa2);
frm.add(txf1);
frm.setVisible(true);
}
catch(Exception e)
{
System.out.println("Error:"+e);
}
}
static class ActLis implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Button btn=(Button) e.getSource();
if(btn==btn1)
{
test_client.txa1.setText("Waiting for connecting with server("+txf1.getText()+")...\n");
System.out.println("Waiting for connecting with server...");
txf1.setEditable(false);
cs.start();
cr.start();
}
else if(btn==btn2)
System.exit(0);
else
System.out.println("No Button Click!");
}
}
static class WinLis extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
frm.dispose();
System.exit(0);
}
}
}
Server執行結果
Client執行結果
透過Socket、類別繼承和AWT的練習,可以讓JAVA更快速的上手。
沒有留言:
張貼留言