字节传输
客户端
//传送内容为:ABCD(4个字节)+长度(4个字节)+字符串字节流
public class ClientByte {
@Test
public void clientRun() throws Exception{
//1.连接服务器
Socket client = new Socket("127.0.0.1", 33905);
OutputStream os = client.getOutputStream();
//2.拼凑字节数组
byte[] startChar = new byte[4];
startChar[0] = 0x41;
startChar[1] = 0x42;
startChar[2] = 0x43;
startChar[3] = 0x44;
String content = "hello,客户端传送的消息!";
byte[] dataArr = content.getBytes("UTF-8");
byte[] size = intToBytes(dataArr.length);
byte[] request = new byte[startChar.length + size.length + dataArr.length];
//3.合并字节数组
System.arraycopy(startChar,0,request,0,4);
System.arraycopy(size,0,request,4,size.length);
System.arraycopy(dataArr,0,request,8,dataArr.length);
System.out.println("request:"+ Arrays.toString(request));
//4.发送数据
os.write(request);
//5.关闭连接
client.close();
}
//整型转字节数组,低位先存,高位后存
private byte[] intToBytes(Integer v){
byte[] res = new byte[4];
for (int j = 0; j < 4; j++) {
res[j] = (byte) (v & 0xff);
v = v >> 8;
}
return res;
}
}
服务器端
public class ServiceByte {
@Test
public void receive() throws IOException {
while(true){
ServerSocket server = new ServerSocket(33905);
System.out.println("listening..");
Socket accept = server.accept();
InputStream is = accept.getInputStream();
byte[] startChar = new byte[4];
is.read(startChar,0,4);
char[] aChar = getChar(startChar);
System.out.println("startChar--> "+ Arrays.toString(aChar));
byte[] size = new byte[4];
is.read(size,0,4);
int lenth = bytes2Int(size);
System.out.println("size--> "+lenth);
byte[] content = new byte[lenth];
is.read(content,0,lenth);
System.out.println(new String(content,"utf-8"));
server.close();
}
}
public char[] getChar(byte[] bytes){
char[] c = new char[bytes.length];
for (int i = 0; i < bytes.length; i++) {
c[i] = (char)bytes[i];
}
return c;
}
public String printHexBinary(byte[] data) {
final char[] hexCode = "0123456789ABCDEF".toCharArray();
StringBuilder r = new StringBuilder(data.length * 2);
for (byte b : data) {
r.append(hexCode[(b >> 4) & 0xF]);
r.append(hexCode[(b & 0xF)]+" ");
}
return r.toString();
}
public int bytes2Int(byte[] bytes )
{
int int1=bytes[0]&0xff;
int int2=(bytes[1]&0xff)<<8;
int int3=(bytes[2]&0xff)<<16;
int int4=(bytes[3]&0xff)<<24;
return int1|int2|int3|int4;
}
}
客户端(Netty)
public class ClientByNettyByte {
@Test
public void testSend() throws Exception {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group) // 注册线程池
.channel(NioSocketChannel.class) // 使用NioSocketChannel来作为连接用的channel类
.remoteAddress(new InetSocketAddress("127.0.0.1", 33905)) // 绑定连接端口和host信息
.handler(new ChannelInitializer<SocketChannel>() { // 绑定连接初始化器
@Override
protected void initChannel(SocketChannel ch) throws Exception {
System.out.println("connected...");
ch.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture cf = b.connect().sync(); // 异步连接服务器
//2.拼凑字节数组
byte[] startChar = new byte[4];
startChar[0] = 0x41;
startChar[1] = 0x42;
startChar[2] = 0x43;
startChar[3] = 0x44;
String content = "hello,客户端传送的消息!";
byte[] dataArr = content.getBytes("UTF-8");
byte[] size = int2Bytes(dataArr.length);
byte[] request = new byte[startChar.length + size.length + dataArr.length];
//3.合并字节数组
System.arraycopy(startChar,0,request,0,4);
System.arraycopy(size,0,request,4,size.length);
System.arraycopy(dataArr,0,request,8,dataArr.length);
System.out.println("request:"+ Arrays.toString(request));
cf.channel().writeAndFlush(Unpooled.copiedBuffer(request));
// cf.channel().writeAndFlush(req);
// cf.channel().closeFuture().sync(); // 异步等待关闭连接channel
System.out.println("closed.."); // 关闭完成
} finally {
group.shutdownGracefully().sync(); // 释放线程池资源
}
}
public byte[] int2Bytes(int integer)
{
byte[] bytes=new byte[4];
bytes[3]=(byte) (integer>>24);
bytes[2]=(byte) (integer>>16);
bytes[1]=(byte) (integer>>8);
bytes[0]=(byte) integer;
return bytes;
}
}
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("client channelActive..");
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
System.out.println("client channelRead..");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
字符串传输
客户端
public class ClientByString {
public static final Integer port = 9898;
public static final String host = "127.0.0.1";
@Test
public void sendToService(){
String content = "hello,我是客户端信息, \n\r 换行重新接受信息";
Socket socket = null;
try {
socket = new Socket(host, port);
//接受服务端发送的数据
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//向服务端发送数据
PrintStream out = new PrintStream(socket.getOutputStream());
out.println(content);
System.out.println("send info to server: "+ content);
//发送后断掉连接
out.close();
input.close();
} catch (Exception e) {
System.out.println("客户端链接异常"+ e);
} finally {
if (socket != null) {
try {
socket.close();
} catch (Exception e) {
socket = null;
System.out.println("关闭异常"+ e);
}
}
}
}
}
服务器端
public class ServiceString {
public static final Integer port = 9898;
@Test
public void receive () throws IOException {
ServerSocket serverSocket = null;
BufferedReader input = null;
try {
//创建一个ServerSocket,port是客户端的端口
serverSocket = new ServerSocket(port);
//从请求队列中取出链接,如果只接受一次则不用使用while循环
Socket socket = serverSocket.accept();
//获取客户端信息
input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String clientContent;
while((clientContent = input.readLine()) != null){
//打印客户端信心
System.out.print(clientContent);
}
//初始化输出流,回复客户端
//获取键盘输出的内容
//将信息发送给客户端
/*
PrintStream out = new PrintStream(socket.getOutputStream());
String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
out.println("open");
out.close();*/
} catch (IOException e) {
System.out.println("服务器异常:" + e);
}finally {
//关闭
input.close();
serverSocket.close();
}
}
}
参考网址
Java Socket编程----通信是这样炼成的
Java Socket编程基础及深入讲解
Java Socket技术总结
JAVA Socket详解
int型与byte型数组的转换