import java.io.*;
import java.util.*;
import javax.microedition.io.*;
class TCPConn
implements Runnable {
static private String ServerURL = "socket://127.0.0.1:7806";
// static private String ServerURL = "socket://60.28.33.84:7805";
// static private String ServerURL = "socket://192.168.0.101:7805";
static private final int VER = 1;
// private SocketConnection socket = null;
private StreamConnection socket = null;
private DataInputStream socket_dis = null;
private DataOutputStream socket_dos = null;
//debug
// int sendCounter=0,receCounter=0;
private Vector
rPool = new Vector() //里面存的是DataPackage
, sPool = new Vector() //里面存的是字节数组
;
private Sender sender = null;
private Receiver receiver = null;
public boolean exit = false;
private int sByteCount = 0, rByteCount = 0;
// public int playerID = -1;
//构造函数
TCPConn() {}
//在第一次调用send()时,线程会被激活,但只做一件事,即打开socket,启动收发子线程
public void run() {
buildConn();
}
//关闭连接,停掉收发线程
public final void closeConn() {
try {
if (sender != null) {
sender.stop();
}
if (receiver != null) {
receiver.stop();
}
if (socket != null) {
socket.close();
}
socket = null;
if (socket_dis != null) {
socket_dis.close();
}
if (socket_dos != null) {
socket_dos.close();
}
}
catch (Exception e) {}
exit = true;
}
//供外部调用发送数据
//此方法只向Vector中添加一个项目
public final void send(int commID, String s, byte[] sbuf) {
byte[] buf = DataPkg.enCode(VER, commID /*, playerID*/, s, sbuf);
sPool.addElement(buf);
//当外部调用发送时,如果没有建立连接那么建立连接(这里是采用线程进行连接)
if (socket == null) {
try {
new Thread(this).start();
}
catch (Exception e) {}
}
}
//等待接收某包,超时以秒计
synchronized public DataPkg waitForReceive(int commID, int timeOut) {
DataPkg tmpdp = null;
for (int t = 0; t < timeOut << 2; t++) { //按秒数乘以4
try {
wait(250);
for (int i = 0; i < rPool.size(); i++) {
tmpdp = (DataPkg) rPool.elementAt(i);
if (tmpdp.commID == commID) {
rPool.removeElementAt(i);
return tmpdp;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
//供外界得到接收到的包
synchronized public final DataPkg receive() {
DataPkg tmpdp = null;
try {
if (rPool.size() > 0) {
tmpdp = (DataPkg) rPool.firstElement();
rPool.removeElement(tmpdp);
//System.out.println("commID="+tmpdp.commID);
}
}
catch (Exception e) {
}
return tmpdp;
}
public int getRcvCount() {
return this.rByteCount;
}
public int getSndCount() {
return this.sByteCount;
}
//-------------------------------------------------------------------------------------------
// 这里下面主要用来实现接收和发送,不能被外部调用
//-------------------------------------------------------------------------------------------
//建立连接,此方法在用户要发送数据时被调用
private final boolean buildConn() {
//先关掉老的连接
closeConn();
try {
//建立新的连接
// socket = (SocketConnection) Connector.open(ServerURL,
// Connector.READ_WRITE, true);
socket = (StreamConnection) Connector.open(ServerURL,
Connector.READ_WRITE, true);
socket_dis = socket.openDataInputStream();
socket_dos = socket.openDataOutputStream();
//启动线程
sender = new Sender(); //启动发送
receiver = new Receiver(); //启动接收
}
catch (Exception e) {
System.out.println("Error in TCPConn.buildConn():");
e.printStackTrace();
exit = true;
return false;
}
exit = false;
return true;
}
//真正的从网络接收数据,被Receiver调用
private final boolean receiveImpl() {
try {
int pkg_length = socket_dis.readInt();
if (pkg_length > 0) {
byte[] buf = new byte[pkg_length];
// socket_dis.read(buf);//这样读会有后患
for (int i = 0; i < pkg_length; i++) {
buf[i] = (byte) socket_dis.read();
}
if (buf != null) {
DataPkg dp = DataPkg.deCode(buf);
this.rPool.addElement(dp);
//System.out.println("-------- r -------\n"+dp.strData);
//debug
}
this.rByteCount += pkg_length + 4 + 20; //pkg_length自身长4bytes,下层IP包会再加20bytes
}
}
catch (Exception e) {
System.out.print(" error in receiveImpl():");
e.printStackTrace();
return false;
}
return true;
}
//实现发送数据到网络,只被sender调用
private final boolean sendImpl(byte[] buf) {
//开始发送
try {
if (buf != null) {
//System.out.println("here");
socket_dos.writeInt(buf.length);
socket_dos.write(buf);
//socket_dos.flush();//把此方法提到外面去,以使在需要时再刷出去
this.sByteCount += buf.length + 20; //下层IP包会加20字节
//debug
}
}
catch (Exception e) {
System.out.print(" error in sendImpl():");
e.printStackTrace();
return false;
}
return true;
}
private final boolean flush() {
try {
socket_dos.flush();
}
catch (IOException ex) {
ex.printStackTrace();
return false;
}
return true;
}
//接收器
class Receiver
implements Runnable {
private Thread self;
Receiver() {
self = new Thread(this);
self.start();
}
public final void stop() {
self = null;
}
public void run() {
final Thread currentThread = Thread.currentThread();
while (self == currentThread) {
try {
//如果没有接收成功,则退出接收
// receCounter++;
if (!receiveImpl()) {
stop();
}
synchronized (this) {
wait(100);
}
}
catch (Exception e) {}
;
}
closeConn();
// GameCanvas.chatBox.setString(GameCanvas.chatBox.getString()+"\nreceived end. ");
}
}
//发送器
class Sender
implements Runnable {
private Thread self;
private int sendPeriod = 100; //通过调节此值可更改发送周期
Sender() {
self = new Thread(this);
self.start();
}
public final void stop() {
self = null;
}
public void run() {
final Thread currentThread = Thread.currentThread();
while (self == currentThread) {
try {
// if (sPool.size() > 0) {
// System.out.println(sPool.size());
// }
for (int i = 0; i < sPool.size(); i++) {
byte[] tmpBuf = (byte[]) sPool.firstElement();
sPool.removeElement(tmpBuf);
//如果没有发送成功,则退出
if (!sendImpl(tmpBuf)) {
stop();
}
}
flush(); //在处理完所有的包之后,再刷出去
synchronized (this) {
wait(sendPeriod);
}
}
catch (Exception e) {
e.printStackTrace();
stop();
}
}
// GameCanvas.chatBox.setString(GameCanvas.chatBox.getString()+"\nsend end. ");
closeConn();
}
}
}
//用于存放接收的数据包
class DataPkg {
byte ver = -1;
byte commID = -1;
// int sender = -1;
short binDataLength = -1;
String strData = null;
byte[] binData = null;
boolean haveData = false;
DataPkg() {}
//给收到的
java_Nio_server_and_j2me_client.rar_J2ME SERVER_NIO_j2me_j2me ni
版权申诉
117 浏览量
2022-09-22
17:37:23
上传
评论
收藏 18KB RAR 举报
小贝德罗
- 粉丝: 69
- 资源: 1万+
最新资源
- sony 索尼IMX334摄像头模组电路板AD版硬件PCB图(6层板).zip
- 基于flask和echarts融合交易策略的bitfinex可视化微服务.zip
- 包含了wvp-assist.tar wvp-talk.tar zlmediakit.tar .
- 3r4efgh53wgrf43tw
- 2024新版Java基础从入门到精通全套视频+资料下载
- Spring AI大模型视频教程+ChatGPT视频教程+OpenAI大模型视频教程(资料+视频教程)
- ABB工业机器人教程PDF版本
- 123321123323211
- yolov8实战第八天-pyqt5-yolov8实现车牌识别系统(论文(8700+字+数据集+完整部署代码+代码使用说明)
- 三相桥式全桥整流电路MATALB Simulink仿真文件
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈