Problem with sending file via socket in Base64

68 Views Asked by At

I'm currently working on a Mail Client that can send Emails in MIME format in C#, but I'm only allow to use Socket (System.Net.Sockets) for implementation. This is the Java server side used for this project: Test-Mail-Server

For testing purposes, I tried to convert a file data into base64 string, then it is sent via socket like this:

Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Connect(IPAddress.Parse("127.0.0.1"), 2225);
client.Send(Encoding.ASCII.GetBytes("HELO test.com\r\n"));
client.Send(Encoding.ASCII.GetBytes("MAIL FROM: <[email protected]>\r\n"));
client.Send(Encoding.ASCII.GetBytes("RCPT TO: <[email protected]>\r\n"));
client.Send(Encoding.ASCII.GetBytes("DATA\r\n"));

byte[] data = File.ReadAllBytes(@"D:\test.docx");
string contentBase64 = Convert.ToBase64String(data);
client.Send(Encoding.ASCII.GetBytes(contentBase64));
client.Send(Encoding.ASCII.GetBytes(".\r\n"));

I got this warning:

An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
io.netty.handler.codec.TooLongFrameException: frame length (over 74240) exceeds the allowed maximum (16384)
        at io.netty.handler.codec.LineBasedFrameDecoder.fail(LineBasedFrameDecoder.java:150)
        at io.netty.handler.codec.LineBasedFrameDecoder.decode(LineBasedFrameDecoder.java:122)
        at io.netty.handler.codec.DelimiterBasedFrameDecoder.decode(DelimiterBasedFrameDecoder.java:232)
        at io.netty.handler.codec.DelimiterBasedFrameDecoder.decode(DelimiterBasedFrameDecoder.java:216)
        at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
        at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
        at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1434)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
        at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
        at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:965)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:647)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:582)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:499)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:461)
        at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
        at java.lang.Thread.run(Unknown Source)

But it was fine when I sent it without converting it into Base64.

I also asked Copilot and Chat-GPT for solution like this, but it still does not work:

static void SendFile(NetworkStream stream, string filePath)
    {
        byte[] buffer = new byte[4096];
        int bytesRead;

        using (FileStream fileStream = new FileStream(filePath, FileMode.Open))
        using (MemoryStream memoryStream = new MemoryStream())
        {
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                // Convert the chunk to Base64 and write it to the memory stream
                string base64Chunk = Convert.ToBase64String(buffer, 0, bytesRead);
                byte[] base64Bytes = Encoding.ASCII.GetBytes(base64Chunk);
                memoryStream.Write(base64Bytes, 0, base64Bytes.Length);
            }

            // Send the entire Base64 content in one go
            stream.Write(memoryStream.ToArray(), 0, (int)memoryStream.Length);
        }

        Console.WriteLine("File sent successfully.");
    }

What should I do?

0

There are 0 best solutions below