{"record":{"id":"add9140d132ccdbd","repo":"egametang/ET","slug":"socket-set-buffer-error-this-sendbuffer-first-le","errorCode":null,"errorMessage":"socket set buffer error: {this.sendBuffer.First.Length}, {this.sendBuffer.FirstIndex}","messagePattern":"socket set buffer error: (.+?), (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.core/Scripts/Core/Share/Network/TChannel.cs","lineNumber":311,"sourceCode":"\t\t\t\t\tthis.isSending = true;\n\n\t\t\t\t\tint sendSize = this.sendBuffer.ChunkSize - this.sendBuffer.FirstIndex;\n\t\t\t\t\tif (sendSize > this.sendBuffer.Length)\n\t\t\t\t\t{\n\t\t\t\t\t\tsendSize = (int)this.sendBuffer.Length;\n\t\t\t\t\t}\n\t\t\t\t\tthis.outArgs.SetBuffer(this.sendBuffer.First, this.sendBuffer.FirstIndex, sendSize);\n\t\t\t\t\t\n\t\t\t\t\tif (this.socket.SendAsync(this.outArgs))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\n\t\t\t\t\tHandleSend(this.outArgs);\n\t\t\t\t}\n\t\t\t\tcatch (Exception e)\n\t\t\t\t{\n\t\t\t\t\tthrow new Exception($\"socket set buffer error: {this.sendBuffer.First.Length}, {this.sendBuffer.FirstIndex}\", e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic void OnSendComplete(SocketAsyncEventArgs o)\n\t\t{\n\t\t\tHandleSend(o);\n\t\t\t\n\t\t\tthis.isSending = false;\n\t\t\t\n\t\t\tthis.Service.Queue.Enqueue(new TArgs() { Op = TcpOp.StartSend, ChannelId = this.Id});\n\t\t}\n\n\t\tprivate void HandleSend(SocketAsyncEventArgs e)\n\t\t{\n\t\t\tif (this.socket == null)\n\t\t\t{\n\t\t\t\treturn;","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.core/Scripts/Core/Share/Network/TChannel.cs#L293-L329","documentation":"TChannel.StartSend wraps any exception from outArgs.SetBuffer / socket.SendAsync with the sendBuffer chunk length and FirstIndex. SetBuffer throws when offset/count is outside the underlying array bounds, and SendAsync throws when the socket is in a bad/closed state.","triggerScenarios":"sendBuffer.FirstIndex advanced past the chunk length (buffer accounting bug), or the socket was disposed between the length check and SendAsync.","commonSituations":"Concurrent dispose of the channel mid-send, a circular-buffer index that went out of range, or a reused SocketAsyncEventArgs after teardown.","solutions":["Re-check socket != null inside the loop (the code already does) and also after SendAsync failures.","Ensure FirstIndex never exceeds sendBuffer.First.Length before SetBuffer.","Treat the wrapped inner exception as the real cause and surface it."],"exampleFix":"// before\nthis.outArgs.SetBuffer(this.sendBuffer.First, this.sendBuffer.FirstIndex, sendSize);\n// after\nif (this.sendBuffer.FirstIndex + sendSize > this.sendBuffer.First.Length) sendSize = this.sendBuffer.First.Length - this.sendBuffer.FirstIndex;\nthis.outArgs.SetBuffer(this.sendBuffer.First, this.sendBuffer.FirstIndex, sendSize);","handlingStrategy":"try-catch","validationCode":"if (sendBuffer.FirstIndex + sendSize > sendBuffer.First.Length)\n    sendSize = sendBuffer.First.Length - sendBuffer.FirstIndex;","typeGuard":"null","tryCatchPattern":"try { StartSend(); }\ncatch (Exception e) when (e.Message.StartsWith(\"socket set buffer error\"))\n{ OnError(...); }","preventionTips":["Clamp sendSize to the remaining chunk length before SetBuffer.","Re-check socket != null after async failures.","Surface the wrapped inner exception for diagnosis."],"tags":["network","tcp","socket","csharp"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}