Stable-Diffusion-V1-5 硬件选型与云平台成本优化指南

核心内容摘要

【小沐学AI】解锁Claude Code,小白也能玩转AI编程
C++算法(9)链表

解决ViewPager嵌套滑动冲突:android-auto-scroll-view-pager最佳实践

代码背景博主想实现一个跨平台通信机制来连接LSP服务端想通过unix domian socket来实现这个。

在java实现客户端连接时出现了问题JDK 原生搞不定 Windows 命名管道Java 的网络库只认 Socket 家族不认“文件”家族。

所以想直接访问这个通道就必须用 Kernel32 。

问题分析描述 在 Windows 上如果用一个线程 ReadFile 阻塞等数据主线程想 WriteFile 发消息时会直接卡死。

博主在测试过程中发现能收到服务端的通知但是在发送消息后服务端无法收到。

经过判断是在发送时卡住然后研究出具体原因。

由此记录一下过程原因 同步模式下读和写共用同一个句柄锁。

读不完锁不放写不进。

避坑指南 在 Windows 环境下 必须先“轮询”再“读取” 。

使用 PeekNamedPipe 检查是否有数据。

没数据就 Thread.sleep(

让出句柄锁。

选择同步的理由代码简洁度 重叠 I/O 在 Java/JNA 里的实现非常臃肿容易引入内存泄漏或指针错误。

兼容性 LSP 服务端通常一次只允许一个连接双句柄方案可能会导致服务端报错“管道忙”。

代码实现packageorg.example.lspClient;importcom.sun.jna.platform.win

Kernel32;importcom.sun.jna.platform.win

WinBase;importcom.sun.jna.platform.win

WinNT;importcom.sun.jna.ptr.IntByReference;importorg.tinylog.Logger;importjava.io.*;importjava.net.StandardProtocolFamily;importjava.net.UnixDomainSocketAddress;importjava.nio.ByteBuffer;importjava.nio.channels.SocketChannel;importjava.nio.charset.StandardCharsets;importjava.nio.file.Path;importjava.util.Arrays;importjava.util.function.Consumer;/** * 跨平台 UDS 传输层具有 LSP 协议感知能力 */publicclassUdsTransportimplementsCloseable{privatefinalbooleanisWindows;privateWinNT.HANDLE hPipe;privateSocketChannelchannel;privatefinalByteArrayOutputStreambuffernewByteArrayOutputStream();privateConsumerStringmessageListener;privatevolatilebooleanrunningtrue;publicUdsTransport(StringsocketPath)throwsIOException{StringosSystem.getProperty(os.name).toLowerCase();this.isWindowsos.contains(win);if(isWindows){connectWindowsPipe(socketPath);}else{connectUnixSocket(socketPath);}startReadingThread();}publicvoidsetOnMessage(ConsumerStringlistener){this.messageListenerlistener;}privatevoidconnectWindowsPipe(StringpipeName)throwsIOException{this.hPipeKernel

INSTANCE.CreateFile(pipeName,WinNT.GENERIC_READ|WinNT.GENERIC_WRITE,0,null,WinNT.OPEN_EXISTING,0,null);if(WinBase.INVALID_HANDLE_VALUE.equals(hPipe)){interrorKernel

INSTANCE.GetLastError();thrownewIOException(Failed to connect to Named Pipe: pipeName (Error: error));}}privatevoidconnectUnixSocket(StringsocketPath)throwsIOException{this.channelSocketChannel.open(StandardProtocolFamily.UNIX);this.channel.connect(UnixDomainSocketAddress.of(Path.of(socketPath)));}publicvoidsendMessage(StringjsonContent)throwsIOException{byte[]bodyjsonContent.getBytes(StandardCharsets.UTF_

;StringheaderContent-Length: body.length\r\n\r\n;writeRaw(header.getBytes(StandardCharsets.US_ASCII));writeRaw(body);}privatevoidwriteRaw(byte[]bytes)throwsIOException{if(isWindows){IntByReferencewrittennewIntByReference();booleansuccessKernel

INSTANCE.WriteFile(hPipe,bytes,bytes.length,written,null);if(!success){interrKernel

INSTANCE.GetLastError();thrownewIOException(WriteFile failed with error: err);}if(written.getValue()bytes.length){Logger.warn(Partial write detected: written.getValue()/bytes.length);return;}}else{ByteBuffernioBufferByteBuffer.wrap(bytes);while(nioBuffer.hasRemaining()){intwrittenchannel.write(nioBuffer);if(written

{thrownewIOException(Channel write stalled);}}}Logger.info(Wrote bytes to: Arrays.toString(bytes));}privatevoidstartReadingThread(){ThreadthreadnewThread(()-{byte[]readBuffernewbyte[8192];try{while(running){intnreadToBuffer(readBuffer);if(n

{synchronized(buffer){buffer.write(readBuffer,0,n);}processBuffer();}else{// 给WriteFile 竞争句柄锁的机会Thread.sleep(

;}}}catch(Exceptione){if(running)System.err.println(Transport read error: e.getMessage());}},UdsTransport-Reader);thread.setDaemon(true);thread.start();}privateintreadToBuffer(byte[]target)throwsIOException{if(isWindows){IntByReferenceavailnewIntByReference();// 轮询是否有数据booleanpeekOkKernel

INSTANCE.PeekNamedPipe(hPipe,null,0,null,avail,null);if(!peekOk){interrKernel

INSTANCE.GetLastError();if(err

thrownewEOFException(Pipe closed);return0;}if(avail.getValue()

{return0;// 当前没数据返回 0 让出 CPU 和句柄锁}IntByReferencereadnewIntByReference();// 此时 ReadFile 不会阻塞因为它已经知道有数据了booleansuccessKernel

INSTANCE.ReadFile(hPipe,target,target.length,read,null);if(!success){interrKernel

INSTANCE.GetLastError();if(err

thrownewEOFException(Pipe closed);if(err

returntarget.length;// ERROR_MORE_DATAthrownewIOException(ReadFile failed: err);}returnread.getValue();}else{ByteBuffernioBufByteBuffer.wrap(target);intnchannel.read(nioBuf);if(n-

thrownewEOFException(Socket closed);returnn;}}privatevoidprocessBuffer(){synchronized(buffer){while(true){byte[]databuffer.toByteArray();if(data.length

break;StringtempStrnewString(data,StandardCharsets.US_ASCII);intheaderEndtempStr.indexOf(\r\n\r\n);if(headerEnd-

break;intcontentLength-1;String[]linestempStr.substring(0,headerEnd).split(\r\n);for(Stringline:lines){if(line.toLowerCase().startsWith(content-length:)){contentLengthInteger.parseInt(line.substring(

.trim());}}if(contentLength-

break;inttotalSizeheaderEnd4contentLength;if(data.lengthtotalSize)break;byte[]bodyBytesnewbyte[contentLength];System.arraycopy(data,headerEnd4,bodyBytes,0,contentLength);StringmessagenewString(bodyBytes,StandardCharsets.UTF_

;// 异步回调if(messageListener!null){messageListener.accept(message);}byte[]remainingnewbyte[data.length-totalSize];System.arraycopy(data,totalSize,remaining,0,remaining.length);buffer.reset();try{buffer.write(remaining);}catch(IOExceptionignored){}}}}Overridepublicvoidclose()throwsIOException{runningfalse;if(isWindows){if(hPipe!null)Kernel

INSTANCE.CloseHandle(hPipe);}else{if(channel!null)channel.close();}}}

鉴黄师在线下载-鉴黄师在线下载应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123