用ServerSocket和Socket来编写服务器程序和客户程序,是Java网络编程的最基本的方式。这些服务器程序或客户程序在运行过程中常常会阻塞。例如当一个线程执行ServerSocket的accept()方法时,假如没有客户连接,该线程就会一直等到有了客户连接才从accept()方法返回。再例如当线程执行Socket的read()方法时,如果输入流中没有数据,该线程就会一直等到读入了足够的数据才从read()方法返回。 两种方法可以尝试对比一下
第一种socket编程:
//首先创建socket连接
socket socket = new Socket(address,port);
// 发送请求到服务端面
@param eql 为要发送的字符
public String sendMessageServer(Socket socket, String eql) {
//此方法将前4位做为字节长度,后面跟所发送的字节
try {
String firstMessage = eql + "\n\0";
int meslength = firstMessage.length();
// 将长度转换为无符号byte
byte[] b = toLH(meslength);
//得到字符的字节数
int count = firstMessage.getBytes().length;
byte[] buf = new byte[count + 4];
// 将长度答存入同一个byte数组字
System.arraycopy(b, 0, buf, 0, b.length);
System.arraycopy(firstMessage.getBytes(), 0, buf, 4, count);
out = socket.getOutputStream();
out.write(buf);
out.flush();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
// 接收服务端返回的数据
public String receiveMessageClient(Socket socket) {
String json = "";
try {
in = new InputStreamReader(socket.getInputStream());
int tempchar;
while ((tempchar = in.read()) != -1) {
if (((char) tempchar) != '\r') {
System.out.print((char) tempchar);
json += (char) tempchar +"";
}
}
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
// 将int数据转换为0~4294967295 (0xFFFFFFFF即DWORD)。
public long getUnsignedIntt(int data) {
return data & 0x0FFFFFFFFl;
}
/**
* 将int转为低字节在前,高字节在后的byte数组
*/
private static byte[] toLH(int n) {
byte[] b = new byte[4];
b[3] = (byte) (n & 0xff);
b[2] = (byte) (n >> 8 & 0xff);
b[1] = (byte) (n >> 16 & 0xff);
b[0] = (byte) (n >> 24 & 0xff);
return b;
}
/**
* 将int转为低字节在前,高字节在后的int
*/
private static int toLH2(int in) {
int out = 0;
out = (in & 0xff) << 24;
out |= (in & 0xff00) << 8;
out |= (in & 0xff0000) >> 8;
out |= (in & 0xff000000) >> 24;
return out;
}
}
第二种 非阻试socket 客户端、、、、、、、、、、、、、、、、、、、、、、
//首先建立连接
InetSocketAddress socketAddress = new InetSocketAddress(m_host,
10002);
//获得与SelectionKey关联的SocketChannel
channel = SocketChannel.open(socketAddress);
Charset charset = Charset.forName("UTF-8");// 创建GBK字符集
//将字符转换成字节
String firstMessage = eql + "\n\0";
String json = "";
try {
firstMessage = new String(firstMessage.getBytes(), "UTF-8");
int meslength = firstMessage.getBytes().length;
// 将长度转换为无符号byte
byte[] b = toLH(meslength);
int count = firstMessage.getBytes().length;
byte[] buf = new byte[count + 4];
// 将长度答存入同一个byte数组字
System.arraycopy(b, 0, buf, 0, b.length);
System.arraycopy(firstMessage.getBytes(), 0, buf, 4, count);
//发送数据
channel.write(sendbuffer);
ByteBuffer sendbuffer = ByteBuffer.wrap(buf);
/******* 读取返回数据的前4个字节 *****/
ByteBuffer length = ByteBuffer.allocate(4);
channel.read(length);
//总共字节数
int ss = byteArrayToInt(length.array(), 0);
/******* 读取返回数据 *****/
int readlength = 1024;
ByteBuffer buffer = ByteBuffer.allocate(readlength);// 创建1024字节的缓冲
// int byte_label = 0;
// if (ss <= readlength) {
// channel.read(buffer);
// json = new String(buffer.array(), "UTF-8");
// buffer.clear();
// } else {
// while (!(ss < readlength)) {
// channel.read(buffer);
// //System.arraycopy(buffer.array(), 0, str, byte_label,
// readlength);
// json += new String(buffer.array(), "UTF-8");
// ss = ss - readlength;
// byte_label =+ readlength;
// buffer.clear();
// }
// buffer = ByteBuffer.allocate(ss);
// channel.read(buffer);
// System.arraycopy(buffer.array(), 0, str, byte_label,
// buffer.array().length);
// json = new String(str, "UTF-8");
// channel.close();
// }
//System.out.printf("@%d@\n", ss);
ByteBuffer require = ByteBuffer.allocate(ss);
//将全部字节读完在退出
for (int n_read = 0; n_read < ss; ) {
int n;
n = channel.read(require);
if (n < 0) {
throw new Exception();
}
n_read += n;
}
//json = new String(require.array(), "UTF-8");
//将收到数据以字符串展示
json = new String(require.array(),"UTF-8");
//System.out.printf(json);
//channel.close();
} catch (Exception e) {
throw new EqlException();
}