简单消息服务器,(9条消息)C#开发一个简单的Http服务器及客户端

/*

*

* C#实现了一个最简单的HTTP服务器类,你可以将它嵌入到自己的项目中,或者也可以阅读代码来学习关于HTTP协议的知识。

* 高性能的WEB应用一般都架设在强大的WEB服务器上,例如IIS, Apache, 和Tomcat。然而,HTML是非常灵活的UI标记语言,

* 也就是说任何应用和后端服务都可以提供HTML的生成支持。在这个小小的例子中,像IIS,、Apache这样的服务器消耗的资源太大了,

* 我们需要自己实现一个简单的HTTP服务器,将它嵌入到我们的应用中用来处理WEB请求。我们仅需要一个类就可以实现了,很简单。

*

*

* 如果你编译运行这个项目,你会在浏览器http://localhost:8888/地址下看到页面上生成的示例内容。让我们来简单看一下这个HTTP服务器引擎是怎么实现的。

*/

using System;

using System.Collections;

using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.Threading.Tasks;

namespace SimpleHttpServer

{

public class HttpProcessor

{

public TcpClient socket;

public HttpServer srv;

private Stream inputStream;

public StreamWriter outputStream;

public String http_method;

public String http_url;

public String http_protocol_versionstring;

public Hashtable httpHeaders = new Hashtable();

private static int MAX_POST_SIZE = 10 * 1024 * 1024; // 10MB

public HttpProcessor(TcpClient s, HttpServer srv)

{

this.socket = s;

this.srv = srv;

}

private string streamReadLine(Stream inputStream)

{

int next_char;

string data = "";

while (true)

{

next_char = inputStream.ReadByte();

if (next_char == '\n') { break; }

if (next_char == '\r') { continue; }

if (next_char == -1) { Thread.Sleep(1); continue; };

data += Convert.ToChar(next_char);

}

return data;

}

public void process()

{

// we can't use a StreamReader for input, because it buffers up extra data on us inside it's

// "processed" view of the world, and we want the data raw after the headers

inputStream = new BufferedStream(socket.GetStream());

// we probably shouldn't be using a streamwriter for all output from handlers either

outputStream = new StreamWriter(new BufferedStream(socket.GetStream()));

try

{

parseRequest();

readHeaders();

if (http_method.Equals("GET"))

{

handleGETRequest();

}

else if (http_method.Equals("POST"))

{

handlePOSTRequest();

}

}

catch (Exception e)

{

Console.WriteLine("Exception: " + e.ToString());

writeFailure();

}

outputStream.Flush();

// bs.Flush(); // flush any remaining output

inputStream = null; outputStream = null; // bs = null;

socket.Close();

}

public void parseRequest()

{

String request = streamReadLine(inputStream);

string[] tokens = request.Split(' ');

if (tokens.Length != 3)

{

throw new Exception("invalid http request line");

}

http_method = tokens[0].ToUpper();

http_url = tokens[1];

http_protocol_versionstring = tokens[2];

Console.WriteLine("starting: " + request);

}

public void readHeaders()

{

Console.WriteLine("readHeaders()");

String line;

while ((line = streamReadLine(inputStream)) != null)

{

if (line.Equals(""))

{

Console.WriteLine("got headers");

return;

}

int separator = line.IndexOf(':');

if (separator == -1)

{

throw new Exception("invalid http header line: " + line);

}

String name = line.Substring(0, separator);

int pos = separator + 1;

while ((pos < line.Length) && (line[pos] == ' '))

{

pos++; // strip any spaces

}

string value = line.Substring(pos, line.Length - pos);

Console.WriteLine("header: {0}:{1}", name, value);

httpHeaders[name] = value;

}

}

public void handleGETRequest()

{

srv.handleGETRequest(this);

}

private const int BUF_SIZE = 4096;

public void handlePOSTRequest()

{

// this post data processing just reads everything into a memory stream.

// this is fine for smallish things, but for large stuff we should really

// hand an input stream to the request processor. However, the input stream

// we hand him needs to let him see the "end of the stream" at this content

// length, because otherwise he won't know when he's seen it all!

Console.WriteLine("get post data start");

int content_len = 0;

MemoryStream ms = new MemoryStream();

if (this.httpHeaders.ContainsKey("Content-Length"))

{

content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]);

if (content_len > MAX_POST_SIZE)

{

throw new Exception(

String.Format("POST Content-Length({0}) too big for this simple server",

content_len));

}

byte[] buf = new byte[BUF_SIZE];

int to_read = content_len;

while (to_read > 0)

{

Console.WriteLine("starting Read, to_read={0}", to_read);

int numread = this.inputStream.Read(buf, 0, Math.Min(BUF_SIZE, to_read));

Console.WriteLine("read finished, numread={0}", numread);

if (numread == 0)

{

if (to_read == 0)

{

break;

}

else

{

throw new Exception("client disconnected during post");

}

}

to_read -= numread;

ms.Write(buf, 0, numread);

}

ms.Seek(0, SeekOrigin.Begin);

}

Console.WriteLine("get post data end");

srv.handlePOSTRequest(this, new StreamReader(ms));

}

public void writeSuccess()

{

outputStream.WriteLine("HTTP/1.0 200 OK");

outputStream.WriteLine("Content-Type: text/html;charset=utf-8");

outputStream.WriteLine("Connection: close");

outputStream.WriteLine("");

}

public void writeFailure()

{

outputStream.WriteLine("HTTP/1.0 404 File not found");

outputStream.WriteLine("Connection: close");

outputStream.WriteLine("");

}

}

public abstract class HttpServer

{

protected int port;

TcpListener listener;

bool is_active = true;

public HttpServer(int port)

{

this.port = port;

}

public void listen()

{

listener = new TcpListener(port); //TcpListener(IPAddress localaddr, int port);

listener.Start();

while (is_active)

{

TcpClient s = listener.AcceptTcpClient();

HttpProcessor processor = new HttpProcessor(s, this);

Thread thread = new Thread(new ThreadStart(processor.process));

thread.Start();

Thread.Sleep(1);

}

}

public abstract void handleGETRequest(HttpProcessor p);

public abstract void handlePOSTRequest(HttpProcessor p, StreamReader inputData);

}

public class MyHttpServer : HttpServer

{

public MyHttpServer(int port) : base(port)

{

}

public override void handleGETRequest(HttpProcessor p)

{

Console.WriteLine("request: {0}", p.http_url);

p.writeSuccess();

string jsonstr = "{\"message\":\"ok\",\"nu\":\"367847964498\",\"ischeck\":\"1\",\"com\":\"shunfeng\",\"status\":\"200\",\"condition\":\"F00\",\"state\":\"3\",\"data\":[{\"time\":\"2020-02-18 16:03:48\",\"context\":\"查无结果\",\"ftime\":\"2020-02-18 16:03:48\"}]}";

p.outputStream.WriteLine("这是一个json数据");

p.outputStream.WriteLine(jsonstr);

//p.outputStream.WriteLine("

test server

");

//p.outputStream.WriteLine("Current Time: " + DateTime.Now.ToString());

//p.outputStream.WriteLine("url : {0}", p.http_url);

//

//p.outputStream.WriteLine("

");

//p.outputStream.WriteLine("");

//p.outputStream.WriteLine("");

//p.outputStream.WriteLine("

");

}

public override void handlePOSTRequest(HttpProcessor p, StreamReader inputData)

{

Console.WriteLine("POST request: {0}", p.http_url);

string data = inputData.ReadToEnd();

p.outputStream.WriteLine("

test server

");

p.outputStream.WriteLine("return

");

p.outputStream.WriteLine("postbody:

{0}
", data);

}

}

class Program

{

static void Main(string[] args)

{

HttpServer httpServer;

if (args.GetLength(0) > 0)

{

httpServer = new MyHttpServer(Convert.ToInt16(args[0]));

}

else

{

httpServer = new MyHttpServer(8888);

}

Thread thread = new Thread(new ThreadStart(httpServer.listen));

thread.Start();

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是实现C# Socket聊天的基本步骤: 1. 创建服务器端程序,绑定IP和端口号,然后开始监听客户端的连接请求。 2. 当有客户端连接到服务器端时,服务器端创建一个新的线程,接收该客户端发送的消息。 3. 当服务器端接收到消息后,将消息转发给其他客户端。 4. 创建客户端程序,连接服务器端。 5. 当客户端连接到服务器端后,可以发送消息服务器端。 下面是代码实现: 服务器端: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace Server { class Program { static void Main(string[] args) { StartServer(); } static void StartServer() { int port = 8888; IPAddress ip = IPAddress.Parse("127.0.0.1"); TcpListener listener = new TcpListener(ip, port); listener.Start(); Console.WriteLine("服务器已启动,等待客户端连接..."); while (true) { TcpClient client = listener.AcceptTcpClient(); Console.WriteLine("客户端已连接"); Thread thread = new Thread(new ParameterizedThreadStart(ReceiveMessage)); thread.Start(client); } } static void ReceiveMessage(object obj) { TcpClient client = obj as TcpClient; NetworkStream stream = client.GetStream(); byte[] buffer = new byte[1024]; while (true) { int len = stream.Read(buffer, 0, buffer.Length); string message = Encoding.UTF8.GetString(buffer, 0, len); Console.WriteLine("接收到消息:" + message); SendMessage(message); } } static void SendMessage(string message) { byte[] buffer = Encoding.UTF8.GetBytes(message); for (int i = 0; i < ClientList.Count; i++) { TcpClient client = ClientList[i]; NetworkStream stream = client.GetStream(); stream.Write(buffer, 0, buffer.Length); } } static List<TcpClient> ClientList = new List<TcpClient>(); } } ``` 客户端: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace Client { class Program { static void Main(string[] args) { StartClient(); } static void StartClient() { int port = 8888; IPAddress ip = IPAddress.Parse("127.0.0.1"); TcpClient client = new TcpClient(); client.Connect(ip, port); Console.WriteLine("连接服务器成功"); Thread thread = new Thread(new ThreadStart(ReceiveMessage)); thread.Start(); while (true) { string message = Console.ReadLine(); byte[] buffer = Encoding.UTF8.GetBytes(message); NetworkStream stream = client.GetStream(); stream.Write(buffer, 0, buffer.Length); } } static void ReceiveMessage() { TcpClient client = new TcpClient(); NetworkStream stream = client.GetStream(); byte[] buffer = new byte[1024]; while (true) { int len = stream.Read(buffer, 0, buffer.Length); string message = Encoding.UTF8.GetString(buffer, 0, len); Console.WriteLine("收到消息:" + message); } } } } ``` 在这个实现中,服务器端使用TcpListener监听客户端连接请求,当有客户端连接时,服务器端创建一个新的线程,接收该客户端发送的消息,并将消息转发给其他客户端客户端连接到服务器端后,可以发送消息服务器端,并接收来自服务器端的消息。 需要注意的是,这个实现只能实现简单的聊天,如果需要支持多个客户端之间的私聊、群聊等功能,还需要进一步完善代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值