Java socket , 服务端与客户端多线程交互

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();
}

}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值