如何使用网络浏览器连接到 Tcp 服务器?
How can I connect to a Tcp server using a web browser?
N.B. 那些评论这个问题的人是广泛的(也,否决和关闭):你不需要关注细节。唯一的问题是能够使用浏览器。
问题背景:
我有一个要求:我有一个客户端(myClient.exe)和一个服务器(myServer.exe) 正在侦听端口 #43。
客户端可以发送 WHOIS 和 HTTP(0.9、1.0 和 1.1)风格的 GET/PUT/POST 命令到服务器,服务器应该能够理解和响应任何风格的命令。
用户也应该能够使用网络浏览器连接到服务器。
我手里的东西:
我已经实施了 WHOIS 和 HTTP 规则。我面临的唯一问题是,我无法使用普通的互联网浏览器连接到服务器。
服务器运行在localhost:5000
地址。我尝试使用 Internet-Explorer 连接到服务器,但失败了。浏览器不断尝试,最终显示失败页面。
我现在需要的是:
我需要一个建议,以便我可以修改我的代码以将我的浏览器连接到 myServer.exe.
源代码:
ClientClass
的源代码是 here。
服务器
class ServerProgram
{
static Dictionary<string, string> NameLocationDictionary;
static Dictionary<string, ClientClass> ClientDictionary;
static void Main(string[] args)
{
Console.Title = "Server";
CommandLineParser parser = new CommandLineParser();
parser.Args = new List<string>(args);
parser.FlagChar = new List<string>(new string[] {"-"});
parser.Acquire();
if (parser.Count > 0)
{
//TODO: log file save
if (parser.ContainsOption("-l"))
{
OptionArgsPosition oap = parser.GetArgument("-l");
if (oap != null)
{
LogFile.Name = oap.Argument;
parser.Remove("-l");
}
}
if (parser.ContainsOption("-f"))
{
OptionArgsPosition oap = parser.GetArgument("-f");
if (oap != null)
{
TextFile txtFile = new TextFile();
txtFile.Name = oap.Argument;
string text = txtFile.Read();
string[] lines = text.Split(new string []{ "\r\n"}, StringSplitOptions.RemoveEmptyEntries);
//load to name-location dictionary
foreach (string s in lines)
{
string [] keyValue = s.Split(',');
if (NameLocationDictionary == null)
{
NameLocationDictionary = new Dictionary<string, string>();
}
NameLocationDictionary.Add(keyValue[0], keyValue[1]);
}
parser.Remove("-f");
}
}
}
ClientDictionary = new Dictionary<string, ClientClass>();
if (NameLocationDictionary == null)
{
NameLocationDictionary = new Dictionary<string, string>();
NameLocationDictionary.Add("TONY4", "TONY4-location");
NameLocationDictionary.Add("xyzgy", "xyzgy-location");
NameLocationDictionary.Add("cssbct", "RB-336");
}
if (string.IsNullOrEmpty(LogFile.Name) || string.IsNullOrWhiteSpace(LogFile.Name))
{
LogFile.Name = "log.txt";
}
string ipAddress = Constants.LOCAL_HOST_IP;
int portNo = Constants.PORT_NO;
IPAddress ip = IPAddress.Parse(ipAddress);
TcpListener listener = new TcpListener(ip, portNo);
listener.Start();
Console.WriteLine("Server program started on address [" + Constants.LOCAL_HOST_IP + ":" + Constants.PORT_NO + "]");
//// poll for TCP clients in a 2nd thread
Thread incomingClientThread = new Thread(delegate ()
{
ServerProgram.PollIncomingClientConns(listener);
});
incomingClientThread.Start();
Console.ReadLine();
}
#region catching client connections
static void PollIncomingClientConns(TcpListener listener)
{
try
{
bool keepRunning = true;
while (keepRunning)
{
ClientClass client = new ClientClass(listener);
if (client.IsConnected)
{
Console.WriteLine("Server connected with client [{0}]", client.ID);
ClientDictionary.Add(client.ID, client);
Thread thread = new Thread(delegate ()
{
ServerProgram.ReadFromClient(client);
});
thread.Start();
}
}
throw new Exception();
}
catch (Exception ex)
{
var inner = ex.InnerException as SocketException;
if (inner != null && inner.SocketErrorCode == SocketError.ConnectionReset)
Console.WriteLine("Disconnected in [ServerProgram.Main.catch]");
else
Console.WriteLine(ex.Message);
listener.Stop();
}
}
#endregion
static void ReadFromClient(ClientClass client)
{
try
{
Console.WriteLine("New Thread of [{0}] in [ServerProgram.ReadfromClient", client.ID);
CommandLineParser parser = new CommandLineParser();
parser.FlagChar = new List<string>(new string[] {"-"});
while (client.Tcp.Connected)
{
string args = client.Read();
args = args.Replace('\r', ' ');
args = args.Replace('\n', ' ');
Regex r = new Regex("([^\" ][^ ]*)|(\"[^\"]*\")");
string [] splittedArgs = r.Matches(args).OfType<Match>().Select(m => m.Value).ToArray();
parser.Args = new List<string>(splittedArgs);
parser.Acquire();
if(args.Contains("GET") || args.Contains("PUT") || args.Contains("POST"))
{
List<string> commands = parser.Args;
commands[1] = commands[1].TrimStart(new char[] { '/', ' ', '?'});//recover [name]
if (!args.Contains("HTTP")) // HTTP 0.9
{
#region HTTP 0.9
if (commands[0] == "GET")//HTTP-0.9 request received
{
if (NameLocationDictionary.ContainsKey(commands[1]))
{
string location = NameLocationDictionary[commands[1]];
string responseText = Http09Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.OK);
}
else
{
string responseText = Http09Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.UNKNOWN);
}
}
if (commands[0] == "PUT")
{
if (NameLocationDictionary.ContainsKey(commands[1]))//update [location]
{
NameLocationDictionary[commands[1]] = commands[2];
string responseText = Http09Text.PUT_name_location_Response_Success_5(commands[2]);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "PUT " + commands[1] + " " + commands[2], ActionType.OK);
}
else
{
string responseText = Http09Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "PUT " + commands[1] + " " + commands[2], ActionType.UNKNOWN);
}
}
#endregion
}
else // HTTP 1.0, or, HTTP 1.1 ...
{
#region HTTP 1.0
if (args.Contains(Constants.HTTP10))
{
if (commands[0] == "GET")//HTTP-1.0 request received
{
if (NameLocationDictionary.ContainsKey(commands[1]))
{
string location = NameLocationDictionary[commands[1]];
string responseText = Http10Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.OK);
}
else
{
string responseText = Http10Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.UNKNOWN);
}
}
if (commands[0] == "POST")
{
List<string> comms = commands;
string key = comms[1];
string location = comms[comms.Count - 1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = location;
string responseText = Http10Text.PUT_name_location_Response_Success_5();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.OK);
}
else
{
string responseText = Http10Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.UNKNOWN);
}
}
}
#endregion
#region HTTP 1.1
if (args.Contains(Constants.HTTP11))
{
if (commands[0] == "GET")//HTTP-1.0 request received
{
string key = commands[1];
if (NameLocationDictionary.ContainsKey(key))
{
string location = NameLocationDictionary[key];
string responseText = Http11Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.OK);
}
else
{
string responseText = Http11Text.GET_POST_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.UNKNOWN);
}
}
if (commands[0] == "POST")
{
string lastLine = commands[commands.Count - 1];
string[] keyLocation = lastLine.Split('&');
string[] keyKey = keyLocation[0].Split('=');
string[] locLoc = keyLocation[1].Split('=');
string key = keyKey[1];
string location = locLoc[1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = location;
string responseText = Http11Text.POST_name_location_Response_Success_5();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.OK);
}
else
{
string responseText = Http11Text.GET_POST_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.UNKNOWN);
}
}
}
#endregion
}
}
else
{
#region WHOIS
List<string> comms = parser.Args;
int argCount = comms.Count;
if (argCount == 1)//return location
{
string key = comms[0];
if (NameLocationDictionary.ContainsKey(key))
{
string value = NameLocationDictionary[key];
string text = key + " is in " + value;
client.Write(text);
client.Disconnect();
Console.WriteLine(text);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.OK);
}
else
{
client.Write("ERROR: no entries found!");
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.UNKNOWN);
}
}
if (argCount == 2)
{
string key = comms[0];
string value = comms[1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = value;
client.Write(key + " is in " + value);
client.Disconnect();
Console.WriteLine(key + " is in " + value);
LogFile.Write(client.ClienIPAddess, "PUT " + key + " " + value, ActionType.OK);
}
else
{
client.Write("ERROR: no entries found!");
}
}
#endregion
}
}
}
catch(Exception ex)
{
client.Disconnect();
ClientDictionary.Remove(client.ID);
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
static void ListConnectedClients()
{
while (true)
{
Console.Write("Command prompt # ");
string command = Console.ReadLine();
}
}
}
客户端
public class ClientProgram
{
static string clientID = string.Empty;
static string otherClientID = string.Empty;
static string host = string.Empty;
static int port = -99;
#region void Start()
public static void Start(string[] args)
{
try
{
CommandLineParser parser = new CommandLineParser();
parser.Args = new List<string>(args);
parser.FlagChar = new List<string>(new string[] { "-" });
parser.Acquire();
host = Constants.LOCAL_HOST_IP;
port = Constants.PORT_NO;
if (parser.Options != null)
{
if (parser.Options.Contains("-h"))
{
OptionArgsPosition oap = parser.GetArgument("-h");
if (oap != null)
{
if (oap.Argument != null)
{
host = oap.Argument;
parser.Remove("-h");
}
}
}
if (parser.Options.Contains("-p"))
{
OptionArgsPosition oap = parser.GetArgument("-p");
if (oap != null)
{
if (oap.Argument != null)
{
port = Convert.ToInt32(oap.Argument);
parser.Remove("-p");
}
}
}
if (parser.Options.Contains("-h0")
|| parser.Options.Contains("-h1")
|| parser.Options.Contains("-h9"))
{//HTTPClient
string name = String.Empty;
string location = String.Empty;
//Task<string> response = MyHttpClientClass.Getrequest(ip, port.ToString());
ClientClass client = new ClientClass(host, port);
try
{
Console.Title = "Client " + "[" + client.ID + "]";
bool success = client.Connect();
if (success)
{
Console.WriteLine("Client [{0}] is connected.", client.ID);
ClientProgram.WriteToHttpServer(client, parser);
}
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
}
else//TCP client
{
ClientClass client = new ClientClass(host, port);
try
{
Console.Title = "Client " + "[" + client.ID + "]";
bool success = client.Connect();
if (success)
{
Console.WriteLine("Client [{0}] is connected.", client.ID);
ClientProgram.WriteToTcpServer(client, parser);
}
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static void WriteToHttpServer(ClientClass client, CommandLineParser parser)
{
try
{
if (client.Tcp.Connected)
{
if (parser.Count < 0)
{
client.Disconnect();
Environment.Exit(0);
}
else
{
if (parser.Options.Contains("-h9"))
{
parser.Remove("-h9");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /" + oap.Option + "\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "PUT /" + oapName.Option + "\r\n\r\n" + oapLocation.Option + "\r\n";
client.Write(str);
}
}
}
if (parser.Options.Contains("-h0"))
{
parser.Remove("-h0");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /?" + oap.Option + " HTTP/1.0\r\n<optional header lines>\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "POST /" + oapName.Option + " HTTP/1.0\r\nContent-Length: 72\r\n<optional header lines>\r\n" + oapLocation.Option;
client.Write(str);
}
}
}
if (parser.Options.Contains("-h1"))
{
parser.Remove("-h1");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /?" + oap.Option + " HTTP/1.1\r\nHost: " + host + "\r\n<optional header lines>\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "POST HTTP/1.1\r\nHost: " + host + "\r\nContent-Length: 72\r\n<optional header lines>\r\nname=" + oapName.Option + "&location=" + oapLocation.Option;
client.Write(str);
}
}
}
Console.WriteLine(parser[0].Option);
Console.WriteLine("From server : " + client.Read());
}
}
Console.WriteLine("ClientProgram.WriteToTcpServer.Done");
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
#endregion
#region void WriteToServer()
private static void WriteToTcpServer(ClientClass client, CommandLineParser commands)
{
//...
}
#endregion
}
一个简单的 HTTP 兼容服务器比二进制套接字服务器只领先几步。您已经在写给客户的回复。如果响应的第一行遵循 HTTP 标准,浏览器将能够显示它。
为了说明,这里有几行代码来自我最近的一个项目。
var message = new StringBuilder();
message.Append("HTTP/1.1 200 OK\n\n");
var length = message.Length;
var outgoingBuffer = new ArraySegment<byte>(Encoding.ASCII.GetBytes(message.ToString()));
_client.Close();
MDN 在 https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages.
维护有关 HTTP 请求和响应消息结构的详细文档
N.B. 那些评论这个问题的人是广泛的(也,否决和关闭):你不需要关注细节。唯一的问题是能够使用浏览器。
问题背景:
我有一个要求:我有一个客户端(myClient.exe)和一个服务器(myServer.exe) 正在侦听端口 #43。
客户端可以发送 WHOIS 和 HTTP(0.9、1.0 和 1.1)风格的 GET/PUT/POST 命令到服务器,服务器应该能够理解和响应任何风格的命令。
用户也应该能够使用网络浏览器连接到服务器。
我手里的东西:
我已经实施了 WHOIS 和 HTTP 规则。我面临的唯一问题是,我无法使用普通的互联网浏览器连接到服务器。
服务器运行在localhost:5000
地址。我尝试使用 Internet-Explorer 连接到服务器,但失败了。浏览器不断尝试,最终显示失败页面。
我现在需要的是:
我需要一个建议,以便我可以修改我的代码以将我的浏览器连接到 myServer.exe.
源代码:
ClientClass
的源代码是 here。
服务器
class ServerProgram
{
static Dictionary<string, string> NameLocationDictionary;
static Dictionary<string, ClientClass> ClientDictionary;
static void Main(string[] args)
{
Console.Title = "Server";
CommandLineParser parser = new CommandLineParser();
parser.Args = new List<string>(args);
parser.FlagChar = new List<string>(new string[] {"-"});
parser.Acquire();
if (parser.Count > 0)
{
//TODO: log file save
if (parser.ContainsOption("-l"))
{
OptionArgsPosition oap = parser.GetArgument("-l");
if (oap != null)
{
LogFile.Name = oap.Argument;
parser.Remove("-l");
}
}
if (parser.ContainsOption("-f"))
{
OptionArgsPosition oap = parser.GetArgument("-f");
if (oap != null)
{
TextFile txtFile = new TextFile();
txtFile.Name = oap.Argument;
string text = txtFile.Read();
string[] lines = text.Split(new string []{ "\r\n"}, StringSplitOptions.RemoveEmptyEntries);
//load to name-location dictionary
foreach (string s in lines)
{
string [] keyValue = s.Split(',');
if (NameLocationDictionary == null)
{
NameLocationDictionary = new Dictionary<string, string>();
}
NameLocationDictionary.Add(keyValue[0], keyValue[1]);
}
parser.Remove("-f");
}
}
}
ClientDictionary = new Dictionary<string, ClientClass>();
if (NameLocationDictionary == null)
{
NameLocationDictionary = new Dictionary<string, string>();
NameLocationDictionary.Add("TONY4", "TONY4-location");
NameLocationDictionary.Add("xyzgy", "xyzgy-location");
NameLocationDictionary.Add("cssbct", "RB-336");
}
if (string.IsNullOrEmpty(LogFile.Name) || string.IsNullOrWhiteSpace(LogFile.Name))
{
LogFile.Name = "log.txt";
}
string ipAddress = Constants.LOCAL_HOST_IP;
int portNo = Constants.PORT_NO;
IPAddress ip = IPAddress.Parse(ipAddress);
TcpListener listener = new TcpListener(ip, portNo);
listener.Start();
Console.WriteLine("Server program started on address [" + Constants.LOCAL_HOST_IP + ":" + Constants.PORT_NO + "]");
//// poll for TCP clients in a 2nd thread
Thread incomingClientThread = new Thread(delegate ()
{
ServerProgram.PollIncomingClientConns(listener);
});
incomingClientThread.Start();
Console.ReadLine();
}
#region catching client connections
static void PollIncomingClientConns(TcpListener listener)
{
try
{
bool keepRunning = true;
while (keepRunning)
{
ClientClass client = new ClientClass(listener);
if (client.IsConnected)
{
Console.WriteLine("Server connected with client [{0}]", client.ID);
ClientDictionary.Add(client.ID, client);
Thread thread = new Thread(delegate ()
{
ServerProgram.ReadFromClient(client);
});
thread.Start();
}
}
throw new Exception();
}
catch (Exception ex)
{
var inner = ex.InnerException as SocketException;
if (inner != null && inner.SocketErrorCode == SocketError.ConnectionReset)
Console.WriteLine("Disconnected in [ServerProgram.Main.catch]");
else
Console.WriteLine(ex.Message);
listener.Stop();
}
}
#endregion
static void ReadFromClient(ClientClass client)
{
try
{
Console.WriteLine("New Thread of [{0}] in [ServerProgram.ReadfromClient", client.ID);
CommandLineParser parser = new CommandLineParser();
parser.FlagChar = new List<string>(new string[] {"-"});
while (client.Tcp.Connected)
{
string args = client.Read();
args = args.Replace('\r', ' ');
args = args.Replace('\n', ' ');
Regex r = new Regex("([^\" ][^ ]*)|(\"[^\"]*\")");
string [] splittedArgs = r.Matches(args).OfType<Match>().Select(m => m.Value).ToArray();
parser.Args = new List<string>(splittedArgs);
parser.Acquire();
if(args.Contains("GET") || args.Contains("PUT") || args.Contains("POST"))
{
List<string> commands = parser.Args;
commands[1] = commands[1].TrimStart(new char[] { '/', ' ', '?'});//recover [name]
if (!args.Contains("HTTP")) // HTTP 0.9
{
#region HTTP 0.9
if (commands[0] == "GET")//HTTP-0.9 request received
{
if (NameLocationDictionary.ContainsKey(commands[1]))
{
string location = NameLocationDictionary[commands[1]];
string responseText = Http09Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.OK);
}
else
{
string responseText = Http09Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.UNKNOWN);
}
}
if (commands[0] == "PUT")
{
if (NameLocationDictionary.ContainsKey(commands[1]))//update [location]
{
NameLocationDictionary[commands[1]] = commands[2];
string responseText = Http09Text.PUT_name_location_Response_Success_5(commands[2]);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "PUT " + commands[1] + " " + commands[2], ActionType.OK);
}
else
{
string responseText = Http09Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "PUT " + commands[1] + " " + commands[2], ActionType.UNKNOWN);
}
}
#endregion
}
else // HTTP 1.0, or, HTTP 1.1 ...
{
#region HTTP 1.0
if (args.Contains(Constants.HTTP10))
{
if (commands[0] == "GET")//HTTP-1.0 request received
{
if (NameLocationDictionary.ContainsKey(commands[1]))
{
string location = NameLocationDictionary[commands[1]];
string responseText = Http10Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.OK);
}
else
{
string responseText = Http10Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + commands[1], ActionType.UNKNOWN);
}
}
if (commands[0] == "POST")
{
List<string> comms = commands;
string key = comms[1];
string location = comms[comms.Count - 1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = location;
string responseText = Http10Text.PUT_name_location_Response_Success_5();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.OK);
}
else
{
string responseText = Http10Text.GET_PUT_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.UNKNOWN);
}
}
}
#endregion
#region HTTP 1.1
if (args.Contains(Constants.HTTP11))
{
if (commands[0] == "GET")//HTTP-1.0 request received
{
string key = commands[1];
if (NameLocationDictionary.ContainsKey(key))
{
string location = NameLocationDictionary[key];
string responseText = Http11Text.GET_name_Response_Success_3(location);
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.OK);
}
else
{
string responseText = Http11Text.GET_POST_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.UNKNOWN);
}
}
if (commands[0] == "POST")
{
string lastLine = commands[commands.Count - 1];
string[] keyLocation = lastLine.Split('&');
string[] keyKey = keyLocation[0].Split('=');
string[] locLoc = keyLocation[1].Split('=');
string key = keyKey[1];
string location = locLoc[1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = location;
string responseText = Http11Text.POST_name_location_Response_Success_5();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.OK);
}
else
{
string responseText = Http11Text.GET_POST_name_Response_Fail_4();
client.Write(responseText);
client.Disconnect();
Console.WriteLine(responseText);
LogFile.Write(client.ClienIPAddess, "POST " + key + " " + location, ActionType.UNKNOWN);
}
}
}
#endregion
}
}
else
{
#region WHOIS
List<string> comms = parser.Args;
int argCount = comms.Count;
if (argCount == 1)//return location
{
string key = comms[0];
if (NameLocationDictionary.ContainsKey(key))
{
string value = NameLocationDictionary[key];
string text = key + " is in " + value;
client.Write(text);
client.Disconnect();
Console.WriteLine(text);
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.OK);
}
else
{
client.Write("ERROR: no entries found!");
LogFile.Write(client.ClienIPAddess, "GET " + key, ActionType.UNKNOWN);
}
}
if (argCount == 2)
{
string key = comms[0];
string value = comms[1];
if (NameLocationDictionary.ContainsKey(key))//update [location]
{
NameLocationDictionary[key] = value;
client.Write(key + " is in " + value);
client.Disconnect();
Console.WriteLine(key + " is in " + value);
LogFile.Write(client.ClienIPAddess, "PUT " + key + " " + value, ActionType.OK);
}
else
{
client.Write("ERROR: no entries found!");
}
}
#endregion
}
}
}
catch(Exception ex)
{
client.Disconnect();
ClientDictionary.Remove(client.ID);
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
static void ListConnectedClients()
{
while (true)
{
Console.Write("Command prompt # ");
string command = Console.ReadLine();
}
}
}
客户端
public class ClientProgram
{
static string clientID = string.Empty;
static string otherClientID = string.Empty;
static string host = string.Empty;
static int port = -99;
#region void Start()
public static void Start(string[] args)
{
try
{
CommandLineParser parser = new CommandLineParser();
parser.Args = new List<string>(args);
parser.FlagChar = new List<string>(new string[] { "-" });
parser.Acquire();
host = Constants.LOCAL_HOST_IP;
port = Constants.PORT_NO;
if (parser.Options != null)
{
if (parser.Options.Contains("-h"))
{
OptionArgsPosition oap = parser.GetArgument("-h");
if (oap != null)
{
if (oap.Argument != null)
{
host = oap.Argument;
parser.Remove("-h");
}
}
}
if (parser.Options.Contains("-p"))
{
OptionArgsPosition oap = parser.GetArgument("-p");
if (oap != null)
{
if (oap.Argument != null)
{
port = Convert.ToInt32(oap.Argument);
parser.Remove("-p");
}
}
}
if (parser.Options.Contains("-h0")
|| parser.Options.Contains("-h1")
|| parser.Options.Contains("-h9"))
{//HTTPClient
string name = String.Empty;
string location = String.Empty;
//Task<string> response = MyHttpClientClass.Getrequest(ip, port.ToString());
ClientClass client = new ClientClass(host, port);
try
{
Console.Title = "Client " + "[" + client.ID + "]";
bool success = client.Connect();
if (success)
{
Console.WriteLine("Client [{0}] is connected.", client.ID);
ClientProgram.WriteToHttpServer(client, parser);
}
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
}
else//TCP client
{
ClientClass client = new ClientClass(host, port);
try
{
Console.Title = "Client " + "[" + client.ID + "]";
bool success = client.Connect();
if (success)
{
Console.WriteLine("Client [{0}] is connected.", client.ID);
ClientProgram.WriteToTcpServer(client, parser);
}
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static void WriteToHttpServer(ClientClass client, CommandLineParser parser)
{
try
{
if (client.Tcp.Connected)
{
if (parser.Count < 0)
{
client.Disconnect();
Environment.Exit(0);
}
else
{
if (parser.Options.Contains("-h9"))
{
parser.Remove("-h9");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /" + oap.Option + "\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "PUT /" + oapName.Option + "\r\n\r\n" + oapLocation.Option + "\r\n";
client.Write(str);
}
}
}
if (parser.Options.Contains("-h0"))
{
parser.Remove("-h0");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /?" + oap.Option + " HTTP/1.0\r\n<optional header lines>\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "POST /" + oapName.Option + " HTTP/1.0\r\nContent-Length: 72\r\n<optional header lines>\r\n" + oapLocation.Option;
client.Write(str);
}
}
}
if (parser.Options.Contains("-h1"))
{
parser.Remove("-h1");
if (parser.Count == 1)
{
OptionArgsPosition oap = parser[0];
if (oap != null)
{
string str = "GET /?" + oap.Option + " HTTP/1.1\r\nHost: " + host + "\r\n<optional header lines>\r\n";
client.Write(str);
}
}
if (parser.Count == 2)
{
OptionArgsPosition oapName = parser[0];
OptionArgsPosition oapLocation = parser[1];
if (oapName != null && oapLocation != null)
{
string str = "POST HTTP/1.1\r\nHost: " + host + "\r\nContent-Length: 72\r\n<optional header lines>\r\nname=" + oapName.Option + "&location=" + oapLocation.Option;
client.Write(str);
}
}
}
Console.WriteLine(parser[0].Option);
Console.WriteLine("From server : " + client.Read());
}
}
Console.WriteLine("ClientProgram.WriteToTcpServer.Done");
}
catch (Exception ex)
{
client.Disconnect();
client.Dispose();
client = null;
Console.WriteLine(ex.Message);
}
}
#endregion
#region void WriteToServer()
private static void WriteToTcpServer(ClientClass client, CommandLineParser commands)
{
//...
}
#endregion
}
一个简单的 HTTP 兼容服务器比二进制套接字服务器只领先几步。您已经在写给客户的回复。如果响应的第一行遵循 HTTP 标准,浏览器将能够显示它。
为了说明,这里有几行代码来自我最近的一个项目。
var message = new StringBuilder();
message.Append("HTTP/1.1 200 OK\n\n");
var length = message.Length;
var outgoingBuffer = new ArraySegment<byte>(Encoding.ASCII.GetBytes(message.ToString()));
_client.Close();
MDN 在 https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages.
维护有关 HTTP 请求和响应消息结构的详细文档