Socket服务端,用一个池对象来保存SocketServer接收到的socket链接。
实现过程中注意
接收客户端连接,只要客户端进行了连接,就会触发accept();从而建立连接。如下:
socket=serverSocket.accept();
此时需要new Handler(socket)一个对象,并将其放入线程池中。如下:
executorService.execute(new Handler(socket));
socket服务端,可做的内容如下:
1)根据与客户端约定好的数据格式,例如:数据的前4位代表userName,5-8位代表客户端请求服务端的methodName。等等,提供相应服务。
2)可以根据socket服务端机器的能力强弱,控制线程池大小。并提供实时的服务器链接数,从而让客户端用户能够选择压力较小的服务器进行链接。提供稳定流畅的服务。
3)可自己封装一个java.net.Socket类MySocket,在其对象里放入一个唯一标志例如客服端传递过来userName,进而实现一个userName,同时只能一个点连接上服务端。
下面是代码:
MultiThreadServer
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MultiThreadServer {
private int port=8888;
private ServerSocket serverSocket;
private ExecutorService executorService;//线程池
private final int POOL_SIZE=5;//单个CPU线程池大小
public MultiThreadServer() throws IOException{
serverSocket=new ServerSocket(port);
//Runtime的availableProcessor()方法返回当前系统的CPU数目.
executorService=Executors.newFixedThreadPool(POOL_SIZE);
System.out.println("服务器启动");
}
public void service(){
while(true){
Socket socket=null;
try {
//接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接
socket=serverSocket.accept();
executorService.execute(new Handler(socket));
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
new MultiThreadServer().service();
}
}
class Handler implements Runnable{
private Socket socket;
public Handler(Socket socket){
this.socket=socket;
}
private BufferedOutputStream getWriter(Socket socket) throws IOException
{
OutputStream socketOut = socket.getOutputStream();
BufferedOutputStream buff = new BufferedOutputStream(socketOut);
return buff;
}
private BufferedInputStream getReader(Socket socket) throws IOException
{
InputStream socketIn = socket.getInputStream();
return new BufferedInputStream(socketIn);
}
public String echo(String msg){
return "echo:"+msg;
}
public void run(){
try {
System.out.println("New connection accepted "+socket.getInetAddress()+":"+socket.getPort());
BufferedInputStream bis = getReader(socket);
BufferedOutputStream bos = getWriter(socket);
while (true)
{
byte[] sizeb = new byte[1024];
bis.read(sizeb);
// 根据于客户端约定好的数据格式,执行对应业务。
System.out.println(new String(sizeb));
String echo = " Hi " + socket.getInetAddress();
byte[] response = echo.getBytes();
bos.write(response); //
bos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(socket!=null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
由于我们项目的客户端是C#项目,所以我就直接copy了网络上的一个例子,如下:
ClientThread
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
class ClientThread implements Runnable
{
Socket socket = null;
int id = 0;
public ClientThread(Socket socket, int id)
{
this.socket = socket;
this.id = id;
}
@Override
public void run()
{
OutputStream out = null;
InputStream in = null;
System.out.println("Begin to Chat to server...");
try
{
out = socket.getOutputStream();
in = socket.getInputStream();
// 循环发送与服务端不停的交互数据
while (true)
{
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
doWrite(out);
System.out.println("begin read message from server.");
doRead(in);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
in.close();
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
/**
*
* 读取服务端数据
*
* @param in
*
* @return
*/
public static boolean doRead(InputStream in)
{
// 引用关系,不要在此处关闭流
byte[] bytes = new byte[1024];
try
{
in.read(bytes);
System.out.println("line:" + new String(bytes).trim());
}
catch (IOException e)
{
e.printStackTrace();
}
return true;
}
/**
*
* 发送数据到服务端
*
* @param out
*
* @return
*/
public boolean doWrite(OutputStream out)
{
// 引用关系,不要在此处关闭流
String line = "Hello server, I am client = " + id + "\n";
line = line + "I want you to do something for me";
try
{
out.write(line.getBytes());
out.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
return true;
}
}
ClientMain
import java.io.IOException;
import java.net.Socket;
public class ClientMain
{
public static void main(String[] args)
{
Socket socket = null;
System.out.println("ClientSocket Begin........");
try
{
for (int i = 0; i < 5; i++)
{
socket = new Socket("192.168.6.168", 8888);
new Thread(new ClientThread(socket, i), "ClientThread " + i).start();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}