Я написал приложение сокет-сервера, которое прослушивает и предоставляет услуги другим процессам, в серверном приложении — ту часть, которая прослушивает запросы:
void ListenToClients() {
while (true) {
IPEndPoint ipEP = new IPEndPoint(IPAddress.Any
, mcintPortRequests);
TcpListener listener = new TcpListener(ipEP);
try {
dicParams_t dicParams = null;
dicRegEx_t dicRegEx = null;
listener.Start();
if (mclient != null) {
mclient.Close();
}
mclient = listener.AcceptTcpClient();
mstream = mclient.GetStream();
if (mstream == null && !mstream.CanRead) {
listener.Stop();
return;
}
if (mstream.Read(msarybytRX, 0, msarybytRX.Length) == 0) {
return;
}
string strRX = Encoding.UTF8.GetString
(msarybytRX, 0, msarybytRX.Length);
//Trim off any null terminators
int intNT = strRX.IndexOf("\0");
if (intNT >= 0) {
strRX = strRX.Substring(0, intNT);
}
bool blnHTTPget, blnHTTPpost;
blnHTTPget = blnHTTPpost = false;
if (strRX.StartsWith(mcstrGET)) {
//Remove any framming information
const string cstrGetStartOfParams = "/?";
strRX = strRX.Substring(mcstrGET.Length);
int intStartOfParams = strRX
.IndexOf(cstrGetStartOfParams);
if (intStartOfParams >= 0) {
const string cstrGetEndOfParams = " HTTP/";
strRX = strRX.Substring(intStartOfParams
+ cstrGetStartOfParams.Length);
int intEODofParams = strRX.IndexOf
(cstrGetEndOfParams);
if (intEODofParams >= 0) {
strRX = strRX.Substring(0
, intEODofParams);
blnHTTPget = true;
}
}
} else if (strRX.StartsWith(mcstrPOST)) {
const string cstrPostStartOfParams = "\r\n\r\n";
strRX = strRX.Substring(mcstrPOST.Length);
int intStartOfParams = strRX
.IndexOf(cstrPostStartOfParams);
if (intStartOfParams >= 0) {
const string cstrPostEndOfParams = "\0";
strRX = strRX.Substring(intStartOfParams
+ cstrPostStartOfParams.Length);
int intEODofParams = strRX.IndexOf
(cstrPostEndOfParams);
if (intEODofParams >= 0) {
strRX = strRX.Substring(0
, intEODofParams);
blnHTTPpost = true;
}
}
}
string[] arystrParams = null;
if (blnHTTPget || blnHTTPpost) {
const char cchrParamDelimiter = '&';
arystrParams = strRX.Split
(cchrParamDelimiter);
} else {
//Remove whitespace
string strJSON = string.Empty;
bool blnInString = false;
for (int i = 0; i < strRX.Length; i++) {
if (strRX[i] == '\''
|| strRX[i] == '\"') {
blnInString = !blnInString;
} else if (blnInString == false
&& (strRX[i] == '\n'
|| strRX[i] == '\r'
|| strRX[i] == '\t'
|| strRX[i] == ' ')) {
continue;
}
strJSON += strRX[i];
}
//Not HTML GET or POST, is this a directy JSON
//exchange?
JsonObject jsonRX = JsonSerializer
.Deserialize(strJSON);
if (jsonRX != null) {
arystrParams = jsonRX
.Select(kvp => $"{kvp.Key}={kvp.Value}")
.ToArray();
}
}
if (arystrParams != null
&& arystrParams.Length > 0) {
dicParams = new dicParams_t();
dicRegEx = new dicRegEx_t();
foreach (string strParam in arystrParams) {
const char cchrAssignDelimiter = '=';
string[] arystrParam = strParam.Split
(cchrAssignDelimiter);
if (arystrParam.Length > 0) {
dicParams.Add(arystrParam[0]
, arystrParam[1]);
}
}
if (mfrmSetup == null) {
mfrmSetup = new clsSetupForm();
}
//Ensure the table is clear
mfrmSetup.table.Controls.Clear();
mfrmSetup.table.ColumnStyles.Clear();
mfrmSetup.table.RowStyles.Clear();
if (dicParams.Count > 0
&& mfrmSetup != null
&& mfrmSetup.Visible != true
&& dicParams.ContainsKey(mcstrFormTitle)) {
mfrmSetup.AcceptButton = mfrmSetup.OK;
mfrmSetup.CancelButton = mfrmSetup.Cancel;
foreach (kvpParams_t kvPair in dicParams) {
if (kvPair.Key
.CompareTo(mcstrFormTitle) == 0) {
mfrmSetup.Text = kvPair.Value;
continue;
}
if (kvPair.Key
.CompareTo(mcstrControls) != 0) {
continue;
}
//Translate JSON string into controls array
JsonArray aryControls = JsonSerializer
.Deserialize
(kvPair.Value);
//Process each record of the controls array
int intRow = 0;
foreach (JsonObject objCtrl in aryControls) {
string strLabel, strRegEx, strType;
JsonObject objParams = null;
strLabel = strRegEx = strType = null;
if (objCtrl[mcstrLabel] != null) {
strLabel = objCtrl[mcstrLabel]
.ToString();
}
if (!string.IsNullOrEmpty(strLabel)
&& objCtrl[mcstrRegEx] != null) {
strRegEx = objCtrl[mcstrRegEx]
.ToString();
dicRegEx.Add(strLabel, strRegEx);
}
if (objCtrl[mcstrParams] != null) {
objParams = JsonSerializer
.Deserialize
(objCtrl[mcstrParams]);
}
if (objCtrl[mcstrType] != null) {
strType = objCtrl[mcstrType]
.ToString();
}
if (string.IsNullOrEmpty(strLabel)
|| string.IsNullOrEmpty(strType)) {
continue;
}
//Create and add label to table
Label lblKey = new Label();
lblKey.Text = strLabel + ":";
lblKey.TextAlign = ContentAlignment.MiddleRight;
mfrmSetup.table.Controls.Add(lblKey
, mcintColumnLabels, intRow);
mfrmSetup.table.ColumnStyles.Add
(new ColumnStyle(SizeType.Absolute
, lblKey.Width));
mfrmSetup.table.RowStyles.Add
(new RowStyle(SizeType.Absolute
, lblKey.Height));
//Create and add control to table
CheckBox cbCtrl = null;
ListBox lbCtrl = null;
TextBox tbCtrl = null;
Control ctrl = null;
if (strType.CompareTo(mcstrCtrlCheckBox) == 0) {
cbCtrl = new CheckBox();
if (cbCtrl != null) {
ctrl = cbCtrl;
}
} else if (strType.CompareTo(mcstrCtrlListBox) == 0) {
lbCtrl = new ListBox();
if (lbCtrl != null) {
ctrl = lbCtrl;
}
} else if (strType.CompareTo(mcstrCtrlTextBox) == 0) {
tbCtrl = new TextBox();
if (tbCtrl != null) {
if (!string.IsNullOrEmpty(strRegEx)) {
tbCtrl.TextChanged += TextBoxChanged;
tbCtrl.Tag = strRegEx;
}
ctrl = tbCtrl;
}
}
if (ctrl != null) {
//Add control to table
mfrmSetup.table.Controls.Add(ctrl
, mcintColumnControls, intRow);
intRow++;
ctrl.Anchor = AnchorStyles.None;
//Apply parameters
foreach (var jsonNode in objParams) {
string strKey = jsonNode.Key;
int intTmp;
if (strKey.CompareTo(mcstrName) == 0) {
//Set name first, it helps to identify control when debugging
ctrl.Name = jsonNode.Value.ToString();
continue;
}
if (strKey.CompareTo(mcstrCheckAlign) == 0
&& cbCtrl != null) {
string strCheckAlign = jsonNode.Value
.ToString();
if (strCheckAlign
.CompareTo(mcstrCenter) == 0) {
cbCtrl.CheckAlign = ContentAlignment
.MiddleCenter;
} else if (strCheckAlign
.CompareTo(mcstrLeft) == 0) {
cbCtrl.CheckAlign = ContentAlignment
.MiddleLeft;
} else if (strCheckAlign
.CompareTo(mcstrRight) == 0) {
cbCtrl.CheckAlign = ContentAlignment
.MiddleRight;
}
continue;
}
if (strKey.CompareTo(mcstrHeight) == 0) {
if (int.TryParse(jsonNode.Value.ToString()
, out intTmp)) {
ctrl.Height = intTmp;
}
continue;
}
if (strKey.CompareTo(mcstrTextAlign) == 0
&& tbCtrl != null) {
string strTextAlign = jsonNode.Value
.ToString();
if (strTextAlign
.CompareTo(mcstrCenter) == 0) {
tbCtrl.TextAlign = HorizontalAlignment
.Center;
} else if (strTextAlign
.CompareTo(mcstrLeft) == 0) {
tbCtrl.TextAlign = HorizontalAlignment
.Left;
} else if (strTextAlign
.CompareTo(mcstrRight) == 0) {
tbCtrl.TextAlign = HorizontalAlignment
.Right;
}
continue;
}
if (strKey.CompareTo(mcstrText) == 0) {
ctrl.Text = jsonNode.Value.ToString();
continue;
}
if (strKey.CompareTo(mcstrWidth) == 0) {
if (int.TryParse(jsonNode.Value.ToString()
, out intTmp)) {
ctrl.Width = intTmp;
}
continue;
}
}
}
}
}
DialogResult result = mfrmSetup.ShowDialog();
if (result != DialogResult.OK) {
continue;
}
Console.WriteLine("HERE!");
}
}
//Then, update the code to use JsonObject correctly:
JsonObject objResponse = new JsonObject();
MemoryStream memStream = new MemoryStream
(msarybytRX, 0, msarybytRX.Length);
StreamWriter streamWriter = new StreamWriter(memStream);
streamWriter.Flush();
Console.WriteLine(strRX);
} catch (Exception ex) {
Console.WriteLine($"ERROR: {ex.Message}");
} finally {
listener.Stop();
}
}
}
public Task Start() {
new Thread(async () => ListenToClients()).Start();
return Task.CompletedTask;
}
Когда форма редактируется и клиенту доступна дополнительная информация, клиент отправляет дополнительную информацию на сервер, которая получается задачей, созданной при изменении текстового поля формы.
Я проверил вышеизложенное на https://jsonlint.com/, и ответ: JSON действителен!
Может ли кто-нибудь увидеть, что может быть не так в блоке принимающей задачи?