kingpub

海内存知己,博客若比邻

 

J2ME中使用Socket开发联网程序

在J2ME中基于UDP协议编程一文中介绍了如何使用Datagram和DatagramConnection来开发应用程序,本文将主要讲述在MIDP2.0中使用ServerSocketConnection和SocketConnection来开发联网应用程序。TCP协议是可以保证传输的质量的,这也是他和UDP的一大区别。由于以上谈到的四个类都属于GCF,他们在程序编写方面也非常相似,通常我们在Server端的某个端口监听,当客户端连接服务器的时候,则可以得到一个SocketConnection的实例。通过两端的SocketConnection则可以实现C/S结构的通信了。

  首先看一下,ServerSocketConnection类,它的一个非常重要的方法就是acceptAndOpen()方法,这个方法返回一个SocketConnection实例,从而使得客户端和服务器端可以通过socket通信了。典型的代码如下:

// Create the server listening socket for port 1234

ServerSocketConnection scn = (ServerSocketConnection)

Connector.open("socket://:1234");

// Wait for a connection.

SocketConnection sc = (SocketConnection) scn.acceptAndOpen();

// Set application specific hints on the socket.

sc.setSocketOption(DELAY, 0);

sc.setSocketOption(LINGER, 0);

sc.setSocketOption(KEEPALIVE, 0);

sc.setSocketOption(RCVBUF, 128);

sc.setSocketOption(SNDBUF, 128);

// Get the input stream of the connection.

DataInputStream is = sc.openDataInputStream();

// Get the output stream of the connection.

DataOutputStream os = sc.openDataOutputStream();

// Read the input data.

String result = is.readUTF();

// Echo the data back to the sender.

os.writeUTF(result);

// Close everything.

is.close();

os.close();

sc.close();

scn.close();

..

 

  SocketConnection的使用也是非常简单,通过Connector的open方法我们可以得到一个SocketConnection的实例。

SocketConnection sc = (SocketConnection)

Connector.open("socket://host.com:79");

sc.setSocketOption(SocketConnection.LINGER, 5);

 


InputStream is = sc.openInputStream();

OutputStream os = sc.openOutputStream();


os.write("\r\n".getBytes());

int ch = 0;

while(ch != -1) {

 ch = is.read();

}


is.close();

os.close();

sc.close();

  其实我们在用socket编写程序的时候无非遵循这样的一种规则:服务器端建立监听端口等待连接,客户端通过open()方法与服务器端建立连接,两端通过建立的socket传输数据,关闭连接。

  下图是我在运行WTK中NetworkDemo的时候的截图!代码也一并发表出来。


package socket;

import javax.microedition.midlet.*;

import javax.microedition.io.*;

import javax.microedition.lcdui.*;

import java.io.*;

public class SocketMIDlet extends MIDlet implements CommandListener {

 private static final String SERVER = "Server";

 private static final String CLIENT = "Client";

 private static final String[] names = { SERVER, CLIENT };

 private static Display display;

 private Form f;

 private ChoiceGroup cg;

 private boolean isPaused;

 private Server server;

 private Client client;

 private Command exitCommand = new Command("Exit", Command.EXIT, 1);

 private Command startCommand = new Command("Start", Command.ITEM, 1);

 public SocketMIDlet() {

display = Display.getDisplay(this);

f = new Form("Socket Demo");

cg = new ChoiceGroup("Please select peer",

Choice.EXCLUSIVE, names,null);

f.append(cg);

f.addCommand(exitCommand);

f.addCommand(startCommand);

f.setCommandListener(this);

display.setCurrent(f);

 }

 public boolean isPaused() {

return isPaused;

 }

 public void startApp() {

isPaused = false;

 }

 public void pauseApp() {

isPaused = true;

 }

 public void destroyApp(boolean unconditional) {

if (server != null) {

 server.stop();

}

if (client != null) {

 client.stop();

}

 }

 public void commandAction(Command c, Displayable s) {

if (c == exitCommand) {

 destroyApp(true);

 notifyDestroyed();

} else if (c == startCommand) {

 String name = cg.getString(cg.getSelectedIndex());

 if (name.equals(SERVER)) {

server = new Server(this);

server.start();

 } else {

client = new Client(this);

client.start();

 }

}

 }

}

package socket;

import javax.microedition.midlet.*;

import javax.microedition.io.*;

import javax.microedition.lcdui.*;

import java.io.*;

public class Server implements Runnable, CommandListener {

 private SocketMIDlet parent;

 private Display display;

 private Form f;

 private StringItem si;

 private TextField tf;

 private boolean stop;

 private Command sendCommand = new Command("Send", Command.ITEM, 1);

 private Command exitCommand = new Command("Exit", Command.EXIT, 1);

 InputStream is;

 OutputStream os;

 SocketConnection sc;

 ServerSocketConnection scn;

 Sender sender;

 

 public Server(SocketMIDlet m) {

parent = m;

display = Display.getDisplay(parent);

f = new Form("Socket Server");

si = new StringItem("Status:", " ");

tf = new TextField("Send:", "", 30, TextField.ANY);

f.append(si);

f.append(tf);

f.addCommand(exitCommand);

f.setCommandListener(this);

display.setCurrent(f);

 }

 public void start() {

Thread t = new Thread(this);

t.start();

 }

 public void run() {

try {

 si.setText("Waiting for connection");

 scn = (ServerSocketConnection) Connector.open("socket://:5009");

 // Wait for a connection.

 sc = (SocketConnection) scn.acceptAndOpen();

 si.setText("Connection accepted");

 is = sc.openInputStream();

 os = sc.openOutputStream();

 sender = new Sender(os);

 

 // Allow sending of messages only after Sender is created

 f.addCommand(sendCommand);

 while (true) {

StringBuffer sb = new StringBuffer();

int c = 0;

while (((c = is.read()) != '\n') && (c != -1)) {

 sb.append((char) c);

}

if (c == -1) {

 break;

}

si.setText("Message received - " + sb.toString());

 }

 stop();

 si.setText("Connection is closed");

 f.removeCommand(sendCommand);

} catch (IOException ioe) {

 if (ioe.getMessage().equals("ServerSocket Open")) {

Alert a = new Alert("Server",

"Port 5000 is already taken.",null, AlertType.ERROR);

a.setTimeout(Alert.FOREVER);

a.setCommandListener(this);

display.setCurrent(a);

 } else {

if (!stop) {

 ioe.printStackTrace();

}

 }

} catch (Exception e) {

 e.printStackTrace();

}

 }

 public void commandAction(Command c, Displayable s) {

if (c == sendCommand && !parent.isPaused()) {

 sender.send(tf.getString());

}

if ((c == Alert.DISMISS_COMMAND) || (c == exitCommand)) {

 parent.notifyDestroyed();

 parent.destroyApp(true);

}

 }

/**

* Close all open streams

*/

 public void stop() {

try {

 stop = true;

 if (is != null) {

is.close();

 }

 if (os != null) {

os.close();

 }

 if (sc != null) {

sc.close();

 }

 if (scn != null) {

scn.close();

 }

} catch (IOException ioe) {

 }

}

}

package socket;

import javax.microedition.midlet.*;

import javax.microedition.io.*;

import javax.microedition.lcdui.*;

import java.io.*;

public class Client implements Runnable, CommandListener {

 private SocketMIDlet parent;

 private Display display;

 private Form f;

 private StringItem si;

 private TextField tf;

 private boolean stop;

 private Command sendCommand =

new Command("Send", Command.ITEM, 1);

 private Command exitCommand =

new Command("Exit", Command.EXIT, 1);

 InputStream is;

 OutputStream os;

 SocketConnection sc;

 Sender sender;

 public Client(SocketMIDlet m) {

parent = m;

display = Display.getDisplay(parent);

f = new Form("Socket Client");

si = new StringItem("Status:", " ");

tf = new TextField("Send:", "", 30, TextField.ANY);

f.append(si);

f.append(tf);

f.addCommand(exitCommand);

f.addCommand(sendCommand);

f.setCommandListener(this);

display.setCurrent(f);

 }

 /**

 * Start the client thread

 */

 public void start() {

Thread t = new Thread(this);

t.start();

 }

 public void run() {

try {

 sc = (SocketConnection) Connector.open("socket://localhost:5009");

 si.setText("Connected to server");

 is = sc.openInputStream();

 os = sc.openOutputStream();

 // Start the thread for sending messages - see Sender's main

 // comment for explanation

 sender = new Sender(os);

 

 // Loop forever, receiving data

 while (true) {

StringBuffer sb = new StringBuffer();

int c = 0;

while (((c = is.read()) != '\n') && (c != -1)) {

 sb.append((char) c);

}

if (c == -1) {

 break;

}

// Display message to user

si.setText("Message received - " + sb.toString());

 }

 stop();

 si.setText("Connection closed");

 f.removeCommand(sendCommand);

} catch (ConnectionNotFoundException cnfe) {

 Alert a = new Alert("Client",

"Please run Server MIDlet first",null, AlertType.ERROR);

 a.setTimeout(Alert.FOREVER);

 a.setCommandListener(this);

 display.setCurrent(a);

} catch (IOException ioe) {

 if (!stop) {

ioe.printStackTrace();

 }

} catch (Exception e) {

e.printStackTrace();

 }

}

public void commandAction(Command c, Displayable s) {

 if (c == sendCommand && !parent.isPaused()) {

sender.send(tf.getString());

 }

 if ((c == Alert.DISMISS_COMMAND) || (c == exitCommand)) {

parent.notifyDestroyed();

parent.destroyApp(true);

 }

}

/**

* Close all open streams

*/

public void stop() {

 try {

stop = true; 

if (sender != null) {
 sender.stop();
}

if (is != null) {
 is.close();
}

if (os != null) {
 os.close();
}

if (sc != null) {

 sc.close();

}

 } catch (IOException ioe) {

}

}

}

package socket;

import javax.microedition.midlet.*;

import javax.microedition.io.*;

import javax.microedition.lcdui.*;

import java.io.*;

public class Sender extends Thread {

 private OutputStream os;
 private String message;

 public Sender(OutputStream os) {
this.os = os;
start();
 }

 public synchronized void send(String msg) {
message = msg;
notify();

 }

 public synchronized void run() {
while (true) {
 // If no client to deal, wait until one connects
 if (message == null) {
try {
 wait();
} catch (InterruptedException e) {

}
 }

 if (message == null) {
break;
 }

 try{
os.write(message.getBytes());
os.write("\r\n".getBytes());

 } catch (IOException ioe) {
 ioe.printStackTrace();
}

// Completed client handling, return handler to pool and
// mark for wait
message = null;
 }
}

public synchronized void stop() {

 message = null;
 notify();
}

}



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=751941

posted on 2006-06-08 15:24 xiaofeng 阅读(120) 评论(0)  编辑  收藏


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(2)

随笔分类

随笔档案

文章分类

文章档案

收藏夹

搜索

最新评论

阅读排行榜

评论排行榜