Socket程序知识点:
Socket程序并不是MIDP2.0中要求移动设备厂商必须支持的协议。是一种典型的“请求--应答”模式。
程序需求:
如上图,先运行服务器端程序,然后再运行客户端的程序,可以通过的屏幕上编辑信息然后发送出来,随后在两个程序的屏幕上都会显示接收到的信息。当客户端的程序运行以后,将自动申请连接服务器,连接成功以后,服务端的程序将显示“Connection accepted”的提示信息。
服务器端程序(SocketServer.java):
注意86行一直没有执行到,是因为连接一直通着,没有流的“-1”出现,所以一直在79行的while的循环里执行
1:
import
java.io.InputStream;
2:
import
java.io.OutputStream;
3:
4:
import
javax.microedition.io.Connector;
5:
import
javax.microedition.io.ServerSocketConnection;
6:
import
javax.microedition.io.SocketConnection;
7:
import
javax.microedition.lcdui.Alert;
8:
import
javax.microedition.lcdui.AlertType;
9:
import
javax.microedition.lcdui.Command;
10:
import
javax.microedition.lcdui.CommandListener;
11:
import
javax.microedition.lcdui.Display;
12:
import
javax.microedition.lcdui.Displayable;
13:
import
javax.microedition.lcdui.Form;
14:
import
javax.microedition.lcdui.StringItem;
15:
import
javax.microedition.lcdui.TextField;
16:
import
javax.microedition.midlet.MIDlet;
17:
import
javax.microedition.midlet.MIDletStateChangeException;
18:
19:
public class
SocketServer
extends
MIDlet
implements
Runnable, CommandListener {
20:
21:
private
Command
sendCommand
=
new
Command(
"Send"
, Command.
ITEM
, 1);
22:
private
Command
exitCommand
=
new
Command(
"Exit"
, Command.
EXIT
, 1);
23:
private
Display
display
;
24:
private
Form
f
;
25:
private
StringItem
si
;
26:
private
TextField
tf
;
27:
private
ServerSocketConnection
scn
;
28:
private
SocketConnection
sc
;
29:
private
InputStream
is
;
30:
private
OutputStream
os
;
31:
private boolean
stop
;
32:
33:
public
SocketServer() {
34:
display
= Display.getDisplay(
this
);
35:
f
=
new
Form(
"Socket Server"
);
36:
si
=
new
StringItem(
"Status: "
,
""
);
37:
tf
=
new
TextField(
"send:"
,
""
, 30, TextField.
ANY
);
38:
f
.append(
si
);
39:
f
.append(
tf
);
40:
f
.addCommand(
exitCommand
);
41:
f
.setCommandListener(
this
);
42:
display
.setCurrent(
f
);
43:
44:
Thread t =
new
Thread(
this
);
45:
t.start();
46:
}
47:
48:
protected void
destroyApp(
boolean
arg0)
throws
MIDletStateChangeException {
49:
//
TODO
Auto-generated method stub
50:
51:
}
52:
53:
protected void
pauseApp() {
54:
//
TODO
Auto-generated method stub
55:
56:
}
57:
58:
protected void
startApp()
throws
MIDletStateChangeException {
59:
//
TODO
Auto-generated method stub
60:
61:
}
62:
63:
public void
run() {
64:
try
{
65:
66:
si
.setText(
"Waiting for connection"
);
67:
// 创建一个服务器的ServerSocketConnection连接
68:
scn
= (ServerSocketConnection) Connector.open(
"socket://:5000"
);
69:
// 等待一个连接
70:
sc
= (SocketConnection)
scn
.acceptAndOpen();
71:
System.
out
.println(
"1"
);
72:
// 设置提示信息
73:
si
.setText(
"Connection accepted"
);
74:
is
=
sc
.openInputStream();
75:
os
=
sc
.openOutputStream();
76:
// 连接完成以后允许发送
77:
f
.addCommand(
sendCommand
);
78:
// 读取客户端发送来的信息
79:
while
(
true
) {
80:
StringBuffer sb =
new
StringBuffer();
81:
int
c = 0;
82:
// 读取数据
83:
while
(((c =
is
.read()) !=
'/n'
&& c != -1)) {
84:
sb.append((
char
) c);
85:
}
86:
// 读取数据不成功,正常情况一直在连接状态流一直没读完,不会有"-1"
87:
if
(c == -1) {
88:
break
;
89:
}
90:
// 显示客户端反送过来的信息
91:
si
.setText(
"Message received - "
+ sb.toString());
92:
}
93:
// stop();
94:
si
.setText(
"Connection is closed"
);
95:
f
.removeCommand(
sendCommand
);
// 连接结束,则不显示发送按钮
96:
}
catch
(Exception e) {
97:
if
(e.getMessage().equals(
"ServerSocket Open"
)) {
98:
// 提示端口已经被占用
99:
Alert a =
new
Alert(
"Server"
,
"Port 5000 is already taken."
,
100:
null
, AlertType.
ERROR
);
101:
a.setTimeout(Alert.
FOREVER
);
102:
a.setCommandListener(
this
);
103:
display
.setCurrent(a);
104:
}
else
{
105:
if
(!
stop
) {
106:
e.printStackTrace();
107:
}
108:
}
109:
}
110:
}
111:
112:
// 发送信息
113:
public void
commandAction(Command c, Displayable d) {
114:
if
(c ==
sendCommand
) {
// 按字节发送信息
115:
try
{
116:
os
.write(
tf
.getString().getBytes());
117:
os
.write(
"/r/n"
.getBytes());
118:
}
catch
(Exception e) {
119:
e.printStackTrace();
120:
}
121:
}
122:
if
(c ==
exitCommand
) {
123:
try
{
124:
destroyApp(
false
);
125:
notifyDestroyed();
126:
}
catch
(MIDletStateChangeException e) {
127:
e.printStackTrace();
128:
}
129:
}
130:
}
131:
132:
// 释放资源
133:
private void
stop() {
134:
try
{
135:
stop
=
true
;
136:
if
(
is
!=
null
) {
137:
is
.close();
138:
}
139:
if
(
os
!=
null
) {
140:
os
.close();
141:
}
142:
if
(
sc
!=
null
) {
143:
sc
.close();
144:
}
145:
if
(
scn
!=
null
) {
146:
scn
.close();
147:
}
148:
}
catch
(Exception e) {
149:
//
TODO
: handle exception
150:
}
151:
}
152:
}
153:
客户端程序(SockClient.java):
注意:Alert错误提示界面还有BUG
1:
import
java.io.IOException;
2:
import
java.io.InputStream;
3:
import
java.io.OutputStream;
4:
5:
import
javax.microedition.io.ConnectionNotFoundException;
6:
import
javax.microedition.io.Connector;
7:
import
javax.microedition.io.SocketConnection;
8:
import
javax.microedition.lcdui.Alert;
9:
import
javax.microedition.lcdui.AlertType;
10:
import
javax.microedition.lcdui.Command;
11:
import
javax.microedition.lcdui.CommandListener;
12:
import
javax.microedition.lcdui.Display;
13:
import
javax.microedition.lcdui.Displayable;
14:
import
javax.microedition.lcdui.Form;
15:
import
javax.microedition.lcdui.StringItem;
16:
import
javax.microedition.lcdui.TextField;
17:
import
javax.microedition.midlet.MIDlet;
18:
import
javax.microedition.midlet.MIDletStateChangeException;
19:
20:
public class
SocketClient
extends
MIDlet
implements
Runnable, CommandListener {
21:
22:
private
Command
sendCommand
=
new
Command(
"Send"
, Command.
ITEM
, 1);
23:
private
Command
exitCommand
=
new
Command(
"Exit"
, Command.
EXIT
, 1);
24:
private
Form
f
;
25:
private
Display
display
;
26:
private
StringItem
si
;
27:
private
TextField
tf
;
28:
private
SocketConnection
sc
;
29:
private
InputStream
is
;
30:
private
OutputStream
os
;
31:
private boolean
stop
;
32:
33:
public
SocketClient() {
34:
display
= Display.getDisplay(
this
);
35:
f
=
new
Form(
"SocketClient"
);
36:
si
=
new
StringItem(
"Status:"
,
" "
);
37:
tf
=
new
TextField(
"Send"
,
""
, 30, TextField.
ANY
);
38:
f
.append(
si
);
39:
f
.append(
tf
);
40:
// 添加屏幕按钮
41:
f
.addCommand(
exitCommand
);
42:
f
.addCommand(
sendCommand
);
43:
f
.setCommandListener(
this
);
44:
display
.setCurrent(
f
);
45:
Thread t =
new
Thread(
this
);
46:
t.start();
47:
}
48:
49:
protected void
destroyApp(
boolean
arg0)
throws
MIDletStateChangeException {
50:
//
TODO
Auto-generated method stub
51:
52:
}
53:
54:
protected void
pauseApp() {
55:
//
TODO
Auto-generated method stub
56:
57:
}
58:
59:
protected void
startApp()
throws
MIDletStateChangeException {
60:
//
TODO
Auto-generated method stub
61:
62:
}
63:
64:
public void
run() {
65:
try
{
66:
// 打开一个连接本地服务器的
67:
sc
= (SocketConnection) Connector.open(
"socket://localhost:5000"
);
68:
si
.setText(
"Connected to server"
);
69:
is
=
sc
.openInputStream();
70:
os
=
sc
.openOutputStream();
71:
// 获得服务器传来的信息
72:
while
(
true
) {
73:
StringBuffer sb =
new
StringBuffer();
74:
int
c = 0;
75:
// 读取数据
76:
while
(((c =
is
.read()) !=
'/n'
) && c != -1) {
77:
sb.append((
char
) c);
78:
}
79:
// 读取数据不成功,正常情况一直在连接状态流一直没读完,不会有"-1"
80:
if
(c == -1) {
81:
break
;
82:
}
83:
// 在屏幕上显示信息
84:
si
.setText(
"Message received - "
+ sb.toString());
85:
}
86:
stop();
// 停止连接
87:
si
.setText(
"Connection closed"
);
88:
f
.removeCommand(
sendCommand
);
89:
}
catch
(ConnectionNotFoundException cnfe) {
90:
Alert a =
new
Alert(
"Client"
,
"Please run Server MIDlet first"
,
91:
null
, AlertType.
ERROR
);
92:
a.setTimeout(Alert.
FOREVER
);
93:
//a.setCommandListener(this);//有这句警告屏无法退回
94:
display
.setCurrent(a);
// 显示警告屏
95:
}
catch
(IOException ioe) {
// 出错
96:
if
(!
stop
) {
97:
ioe.printStackTrace();
98:
}
99:
}
catch
(Exception e) {
// 打印出错信息
100:
e.printStackTrace();
101:
}
102:
}
103:
104:
// 释放资源
105:
private void
stop() {
106:
try
{
107:
stop
=
true
;
108:
if
(
is
!=
null
) {
109:
is
.close();
110:
}
111:
if
(
os
!=
null
) {
112:
os
.close();
113:
}
114:
if
(
sc
!=
null
) {
115:
sc
.close();
116:
}
117:
}
catch
(Exception e) {
118:
e.printStackTrace();
119:
}
120:
}
121:
122:
// 发送信息给服务器
123:
public void
commandAction(Command c, Displayable d) {
124:
if
(c ==
sendCommand
) {
125:
try
{
// 发送用户输入数据
126:
os
.write(
tf
.getString().getBytes());
127:
os
.write(
"/r/n"
.getBytes());
128:
}
catch
(Exception e) {
129:
e.printStackTrace();
130:
}
131:
}
132:
if
(c ==
exitCommand
) {
133:
try
{
134:
destroyApp(
false
);
135:
notifyDestroyed();
136:
}
catch
(MIDletStateChangeException e) {
137:
e.printStackTrace();
138:
}
139:
}
140:
}
141:
142:
}
143:

