C#通过HTTP发送图像

16

我有一个用C#编写的小型HTTP服务器,到目前为止,我只需要向发送者发送原始文本。但现在我需要发送一张JPG图片,我不知道该怎么做。

这是我现在拥有的:

// Read the HTTP Request
Byte[] bReceive = new Byte[MAXBUFFERSIZE];
int i = socket.Receive(bReceive, bReceive.Length, 0);

//Convert Byte to String
string sBuffer = Encoding.ASCII.GetString(bReceive);

// Look for HTTP request
iStartPos = sBuffer.IndexOf("HTTP", 1);

// Extract the Command without GET_/ at the beginning and _HTTP at the end
sRequest = sBuffer.Substring(5, iStartPos - 1 - 5);
String answer = handleRequest(sRequest);


// Send the response
socket.Send(Encoding.UTF8.GetBytes(answer));

我想我需要使用文件流而不是字符串,但我真的一点头绪都没有..


你能发一下你的handleRequest方法的部分代码吗?我猜那里是你构建HTTP响应对象并发送回请求浏览器的地方。你需要想办法修改它以支持图片。 - Justin Niessner
1
我有一些胶水,如果你想借的话 :/ - Jeff LaFay
@Martin 如果你正在从文件中读取数据,你可以直接调用 socket.SendFile。请参考这里(msdn.microsoft.com/en-us/library/sx0a40c2.aspx)。 - Arsen Mkrtchyan
2个回答

2

您希望从文件还是位图对象发送?

MemoryStream myMemoryStream = new MemoryStream();
myImage.Save(myMemoryStream);
myMemoryStream.Position = 0;

编辑

// Send the response
SendVarData(socket,memoryStream.ToArray());

如果要通过socket发送MemoryStream,可以使用这里提供的方法。

 private static int SendVarData(Socket s, byte[] data)
 {
            int total = 0;
            int size = data.Length;
            int dataleft = size;
            int sent;

            byte[] datasize = new byte[4];
            datasize = BitConverter.GetBytes(size);
            sent = s.Send(datasize);

            while (total < size)
            {
                sent = s.Send(data, total, dataleft, SocketFlags.None);
                total += sent;
                dataleft -= sent;
            }
            return total;
 }

哎呀,真的有一个可以使用流的Send重载吗? - jgauffin
如果您只想发送文件,则socket.SendFile()是一个选项。但是,这不会提供任何必要的HTTP响应格式化,以便进行正确的响应。 - Justin Niessner
据我所知,没有重载以流作为参数的函数。 - jgauffin
为什么不让 SendVarData 接受一个流作为参数呢?这样似乎更加节省内存。 - jgauffin
1
如果您正在从文件中读取,只需调用 socket.SendFile。请参见此处 (http://msdn.microsoft.com/en-us/library/sx0a40c2.aspx)。 - Arsen Mkrtchyan

2
你为什么要自己创建一个http服务器?为什么不使用开源的呢?比如我的:http://webserver.codeplex.com
public class Example    
{
    private HttpListener _listener;

    public void StartTutorial()
    {
        _listener = HttpListener.Create(IPAddress.Any, 8081);
        _listener.RequestReceived += OnRequest;
        _listener.Start(5);
    }

    private void OnRequest(object source, RequestEventArgs args)
    {
        IHttpClientContext context = (IHttpClientContext)source;
        IHttpRequest request = args.Request;

        IHttpResponse response = request.CreateResponse(context);
        response.Body = new FileStream("Path\\to\\file.jpg");
        response.ContentType = "image\jpeg";
        response.Send();
    }

}
编辑

如果你真的想自己做:

string responseHeaders = "HTTP/1.1 200 The file is coming right up!\r\n" +
"Server: MyOwnServer\r\n" +
"Content-Length: " + new FileInfo("C:\\image.jpg").Length + "\r\n" +
"Content-Type: image/jpeg\r\n" + 
"Content-Disposition: inline;filename=\"image.jpg;\"\r\n" +
"\r\n";

//headers should ALWAYS be ascii. Never UTF8
var headers = Encoding.ASCII.GetBytes(responseHeaders); 
socket.Send(headers, 0, headers.Length);
socket.SendFile("C:\\image.jpg");

因为它非常简单,不像HTTP服务器那样运作。我只接收命令,例如:http://localhost/winamp.play - martinyyyy
真的吗?给我展示一个可以嵌入到 .Net 2.0 应用程序中的 http 服务器。.Net HttpListener 需要管理权限才能订阅某些 uri,不是很灵活。我的观点是,如果你没有足够的 HTTP 知识,你可能会浪费很多时间来尝试让东西工作。使用现有的库应该更有效率。 - jgauffin
1
也许他们的意图是收集有关HTTP和C#的知识?并非所有事情都是为了提高生产力。 - Christoph Böhmwalder
@HackerCow:难道学习的最佳方式不是阅读实际的实现吗? - jgauffin
3
不,学习协议最好的方式是实现它,学习语言最好的方式是在其中实现某些东西(至少对我来说是这样)。 - Christoph Böhmwalder
他的问题中从未提到协议或要求在HTTP中正确执行的方式,他的问题是关于如何在网络层面上实现它。学习HTTP和网络编程都不是小任务,因此我的建议是使用已经可用的东西。我的假设和你的一样有效,因为我们都猜测他的最终目标是什么。但由于他的问题是关于如何在网络层面上实现它,所以我的答案更好,因为它实际上展示了如何使用完整的代码解决方案来实现它。 - jgauffin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接