在线等JAVA高手解决

yilingjingshui 2012-11-01 02:41:32
公司需求要用C#做客户端访问服务器开发,目前初步定的是客户端C#+中间件用JAVA(存放服务器)+DB,中间件处理客户端请求的SQL然后返回数据集,希望大家对这个中间件给点指点
...全文
228 点赞 收藏 14
写回复
14 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
MiceRice 2012-11-02
这里有个,你可以用客户端连上去,不管发什么信息,都会直接发回来。


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class EchoServer {

private static int SOCKET_NUM = 55555;

private DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd HH:mm:ss");

/**
* @param args
*/
public static void main(String[] args) {
new EchoServer().start();
}

public void start() {
try {
Selector selector = bindServer(); // 绑定服务端口,并定义一个事件选择器对象记录套接字通道的事件

/* 通过此循环来遍例事件 */
while (true) {
log("Waiting events.");
int n = selector.select(); // 查询事件如果一个事件都没有,这里就会阻塞
log("Got events: " + n);

ByteBuffer echoBuffer = ByteBuffer.allocate(50); // 定义一个byte缓冲区来存储收发的数据

/* 循环遍例所有产生的事件 */
for (SelectionKey key : selector.selectedKeys()) {
SocketChannel sc;
selector.selectedKeys().remove(key); // 将本此事件从迭带器中删除

/* 如果产生的事件为接受客户端连接(当有客户端连接服务器的时候产生) */
if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {

ServerSocketChannel subssc = (ServerSocketChannel) key.channel(); // 定义一个服务器socket通道

sc = subssc.accept(); // 将临时socket对象实例化为接收到的客户端的socket

sc.configureBlocking(false); // 将客户端的socket设置为异步

sc.register(selector, SelectionKey.OP_READ); // 将客户端的socket的读取事件注册到事件选择器中

System.out.println("Got new client:" + sc);
}
/* 如果产生的事件为读取数据(当已连接的客户端向服务器发送数据的时候产生) */
else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {

sc = (SocketChannel) key.channel(); // 临时socket对象实例化为产生本事件的socket

ByteArrayOutputStream bos = new ByteArrayOutputStream(); // 定义一个用于存储byte数据的流对象,存储全部信息

echoBuffer.clear(); // 先将客户端的数据清空

try {
// 循环读取所有客户端数据到byte缓冲区中,当有数据的时候read函数返回数据长度
// NIO会自动的将缓冲区一次容纳不下的自动分段
int readInt = 0; // 为读取到数据的长度
while ((readInt = sc.read(echoBuffer)) > 0) {
// 如果获得数据长度比缓冲区大小小的话
if (readInt < echoBuffer.capacity()) {

byte[] readByte = new byte[readInt]; // 建立一个临时byte数组,将齐长度设为获取的数据的长度
// 循环向此临时数组中添加数据
for (int i = 0; i < readInt; i++) {
readByte[i] = echoBuffer.get(i);
}

bos.write(readByte); // 将此数据存入byte流中
}
// 否则就是获得数据长度等于缓冲区大小
else {
bos.write(echoBuffer.array()); // 将读取到的数据写入到byte流对象中
}
}
// 当循环结束时byte流中已经存储了客户端发送的所有byte数据
log("Recive msg: " + new String(bos.toByteArray()));
} catch (Exception e) {

e.printStackTrace(); // 当客户端在读取数据操作执行之前断开连接会产生异常信息

key.cancel(); // 将本socket的事件在选择器中删除
break;
}

writeBack(sc, bos.toByteArray()); // 向客户端写入收到的数据
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 绑定服务端口,初始化整个服务
* @throws IOException
*/
private Selector bindServer() throws IOException {
log("Start binding server socket:" + SOCKET_NUM);

Selector selector = Selector.open(); // 定义一个事件选择器对象记录套接字通道的事件

ServerSocketChannel ssc = ServerSocketChannel.open(); // 定义一个异步服务器socket对象

ssc.configureBlocking(false);// 将此socket对象设置为异步

ServerSocket ss = ssc.socket(); // 定义服务器socket对象-用来指定异步socket的监听端口等信息

InetSocketAddress address = new InetSocketAddress(SOCKET_NUM); // 定义存放监听端口的对象

ss.bind(address); // 将服务器与这个端口绑定

ssc.register(selector, SelectionKey.OP_ACCEPT); // 将异步的服务器socket对象的接受客户端连接事件注册到selector对象内

log("Binded socket at:" + SOCKET_NUM);

return selector;
}

private boolean writeBack(SocketChannel sc, byte[] b) {
ByteBuffer echoBuffer = ByteBuffer.allocate(b.length); // 建立这个byte对象的ByteBuffer
echoBuffer.put(b); // 将数据存入

echoBuffer.flip(); // 将缓冲区复位以便于进行其他读写操作
try {
// 向客户端写入数据,数据为接受到数据
sc.write(echoBuffer);
} catch (IOException e) {
e.printStackTrace();
return false;
}
System.out.println("Msg echo back: " + new String(echoBuffer.array()));
return true;
}

private void log(Object msg) {
System.out.println("SERVER [" + dateFormatter.format(new Date()) + "]: " + msg);
}
}
回复
yilingjingshui 2012-11-02
[Quote=引用 12 楼 的回复:]
自己简单研究下NIO吧,核心思想是非阻塞IO,这样就可以用一条线程同时服务N个Socket连接。从而避免线程规模太高导致上下文切换所浪费的开销过大。

其实即便不用Mina,自己实现NIO,也不是很难;只不过用框架的话,首次学习熟悉后,后面就可以节省工作量咯。
[/Quote]
有没有比较好的例子提供个给我借鉴下
回复
MiceRice 2012-11-01
自己简单研究下NIO吧,核心思想是非阻塞IO,这样就可以用一条线程同时服务N个Socket连接。从而避免线程规模太高导致上下文切换所浪费的开销过大。

其实即便不用Mina,自己实现NIO,也不是很难;只不过用框架的话,首次学习熟悉后,后面就可以节省工作量咯。
回复
yilingjingshui 2012-11-01
Mina 这个东西之前没接触过,管理数万~数十万应该是问题不大的话那就可以了,ldh911
可以给点详细的说明吗
回复
MiceRice 2012-11-01
[Quote=引用 8 楼 的回复:]
要满足上千号人同时访问
[/Quote]

那么就是说:可以理解为上千个C#客户端。

每个客户端的访问频度如何?或者说每秒请求量如何?


如果请求量不是非常高的话,Java来应对这个问题不是很大;但不能使用传统IO模型,建议采用NIO技术,也可以考虑用开源成熟的框架来管理网络连接部分,比如:Mina等。
视机器性能,管理数万~数十万应该是问题不大的,再上去就有问题了。
回复
yilingjingshui 2012-11-01
自己再顶下,各位大侠发表发表意见啊
回复
yilingjingshui 2012-11-01
要满足上千号人同时访问
回复
MiceRice 2012-11-01
[Quote=引用 5 楼 的回复:]
客户端与服务器是用socket通信,现在考虑的就是请求量大的问题,会不会崩溃或因网络问题堵塞
[/Quote]

客户端总量有多少?单个客户端的请求量大致如何?
回复
yilingjingshui 2012-11-01
[Quote=引用 4 楼 的回复:]
看你项目大不大,可以用框架,也可以直接写java代码操作DB
[/Quote]
直接操作DB
回复
yilingjingshui 2012-11-01
客户端与服务器是用socket通信,现在考虑的就是请求量大的问题,会不会崩溃或因网络问题堵塞
回复
李陵少 2012-11-01
看你项目大不大,可以用框架,也可以直接写java代码操作DB
回复
MiceRice 2012-11-01
规范化的话,中间层可以提供WebService标准服务。设计好协议报文的结构就好了。

简化的话,也可以参考REST来做,直接走HTTP请求和响应。
回复
yilingjingshui 2012-11-01
高手在哪里啊!自己顶下
回复
相关推荐
发帖
Web 开发
创建于2007-09-28

8.0w+

社区成员

Java Web 开发
申请成为版主
帖子事件
创建了帖子
2012-11-01 02:41
社区公告
暂无公告