站内搜索: 请输入搜索关键词

当前页面: 开发资料首页J2SE 专题J2ME 客户端与J2SE 服务器端的Socket通信

J2ME 客户端与J2SE 服务器端的Socket通信

摘要: J2ME 客户端与J2SE 服务器端的Socket通信

一. J2ME与J2SE中 Socket类的比较

J2SE中:

包结构:import java.net.Socket;
import java.net.ServerSocket;

其中:Socket 用于创建通信客户端,它在服务器程序和客户端程序都要用到。
ServerSocket 用于创建服务器,它在服务器程序用到。
常用的方法:
1.Socket的创建:Socket mySocket=new Socket("localhost",4321);
Socket mySocket=new Socket("192.168.0.1",4321);
该构造函数有两参数,第一个为,要连接的服务器端的IP地址,第二个为,端口号。
2.ServerSocket的创建: ServerSocket server=new ServerSocket(4321);
3.连接的建立: 在服务器端: Socket client=server.accept();
4.输入/出流的获取:
InputStream in= mySocket.getInputStream();
OutputStream out= mySocket.getOutputStream();
在获取了输入/输出流后,就可以从输入流里面读信息了,同样可以向输出流写信息了。

J2ME中:
包结构:import javax.microedition.io.SocketConnection;
import javax.microedition.io.ServerSocketConnection;

其中:SocketConnection 用于创建通信客户端,它在服务器程序和客户端程序都要用到。
ServerSocketConnection 用于创建服务器,它在服务器程序用到。
常用的方法:
1. SocketConnection的创建:
SocketConnection sc = (SocketConnection)
Connector.open("socket://localhost:4321")
2.ServerSocketConnection 的创建:
ServerSocketConnection scn = (ServerSocketConnection)
Connector.open("socket://:4321");
3.连接的建立:
在服务器端:SocketConnection sc = (SocketConnection) scn.acceptAndOpen();
4.输入/出流的获取:InputStream is = sc.openInputStream();
OutputStream os = sc.openOutputStream();

二. 输入/输出流的处理
1.InputStream,OutputStream的使用:
注意:InputStream,OutputStream都是字节流。
InputStream,输入流的读:in.read();
Read()方法有三个重载的方法:
int read() throws IOException
int read(byte[] b) throws IOException
int read(byte[] b, int off,int len)throws IOException
还有个很重要的方法: long skip(long n) throws IOException 用于跳跃,
可以方便读出有效的信息。

OutputStream输出流的写:out.write();
同样Write()方法也有三个重载的方法:
void write(int b) throws IOException
void write(byte[] b) throws IOException
void write(byte[] b, int off, int len) throws IOException

2.使用DataInputStream, DataOutputStream封装InputStream,OutputStream
由于InputStream,OutputStream是字节流,有时候在读写字符串,数字等时,不是很方便。
特别是在读写中文字符串时(因为汉字为双字节的)就更不方便了。
而使用使用DataInputStream, DataOutputStream封装InputStream,OutputStream后,
由于DataInputStream, DataOutputStream分别有读写字符串,
数字的方法,所以用起就方便了。

注意是有时候使用DataInputStream, DataOutputStream更方便,
但是有时候使用InputStream,OutputStream也很方便。

DataInputStream, DataOutputStream与InputStream,OutputStream的关系

java.lang.Object
+--java.io.InputStream
+--java.io.FilterInputStream
+--java.io.DataInputStream

java.lang.Object
+--java.io.OutputStream
+--java.io.FilterOutputStream
+--java.io.DataOutputStream

通常的方法:
DataInputStream dis=new DataInputStream(socket.getInputStream());
DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
DataInputStream dis = new DataInputStream(sc.openInputStream());
DataOutputStream dos = new DataOutputStream(sc.openOutputStream());

DataInputStream的一些常用方法:
readBoolean();
readByte();
readInt();
readChar();
readFloat();
readUTF();等等

对应的DataOutputStream也有相应的方法:
writeBoolean();
writeByte();
writeInt();
writeChar();
writeFloat();
writeUTF();等等

3.J2SE服务器端与J2ME的客户端的通信服务器端(两个类,Server2,Server_thread1)

import java.net.*;
import java.io.*;
import java.util.*;
import java.sql.*;

public class Server2 {

public static void main(String args[]){
ServerSocket server=null;
Server_thread1 thread;
Socket client=null;
int n=0;
while(true){
try{
server=new ServerSocket(4321);
}catch(IOException e){
System.out.println(" ");
}

try{
client=server.accept();
}catch(IOException e){
System.out.println("client:"+client.getInetAddress());
}

if(client!=null){
new Server_thread1(client,n).start();
n++;
System.out.println(" "+client.getInetAddress());
System.out.println(" "+n+" ");
}
}
}
}


import java.net.*;
import java.io.*;
import java.util.*;
import java.sql.*;

public class Server_thread1 extends Thread{
int no;
Socket socket;
Connection con=null;
Statement stmt=null;
OutputStream os=null;
InputStream is=null;
Sender sender;

static String[] str=new String[10];

public Server_thread1(Socket skt,int n) {
no=n;
socket=skt;
for(int i=0;i<10;i++){
str[i]="";
}

try{
is=socket.getInputStream();
os=socket.getOutputStream();
sender = new Sender(os);
} catch(IOException e){}
}

public void run(){
while(true){
try{
StringBuffer sb = new StringBuffer();
int c = 0;
while (((c = is.read()) != '\n') && (c != -1)) {
sb.append((char) c);
}

if (c == -1) {
break;
}
System.out.println("Message received - " + sb.toString());
str[no]=sb.toString();
char ch=str[no].charAt(0);
int id=ch-'0';
sender.send(str[id]);
}catch(Exception e){}
}
}
}



客户端(三个类socketMIDlet,Sender,Client)

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 = {CLIENT};
private static Display display;
private Form f;
private ChoiceGroup cg;
private boolean isPaused;
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 (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(CLIENT)) {
client = new Client(this);
client.start();
}
}
}
}



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
}
}

public synchronized void stop() {
message = null; notify();
}
}


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);
}
public void start() {
Thread t = new Thread(this);
t.start();
}

public void run() {
try {
sc = (SocketConnection)Connector.open("socket://192.168.0.78:4321");
si.setText("Connected to server");
is = sc.openInputStream();
os = sc.openOutputStream(); // Start the thread for sending messages - see Sender's main
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) {}
}
}

注意在这个实验中,服务器端采用了多线程,即每来一个客户端的连接请求到来时,
都响应给它产生一个线程,由各个线程负责与每个客户端的通信。
到此,一个基本的J2ME 客户端与J2SE 服务器端的Socket通信已经到了。



↑返回目录
前一篇: NetBeans 4.1 的J2SE项目结构
后一篇: 基本完成j2se部分的学习