I am developing a UWP VPN Plugin. In later stage it should handle OpenVPN. In the first stage I am trying to understand the VpnPlugin to get it work in the simplest possible way. For testing I am using Android's ToyVpn test Server on a Debian VM (https://android.googlesource.com/platform/development/+/master/samples/ToyVpn/server/linux). Unfortunately the VpnPlugin is poor and lousy documented, no Guideline - no Nothing. The Github examples are useless and not working either, even https://github.com/ysc3839/UWPToyVpn gives only Rough orientation. I was able to successfully do the Handshake with the Server who responds with a Parameter chain. When it Comes to start the Connection, an exception is thrown that the device is not connected. I am running out of Options and any help would greatly appreciated.
public sealed class ToyVpnPlugin : IVpnPlugIn
{
DatagramSocket _datagramSocket;
public async void Connect(VpnChannel channel)
{
//string parameters = default;
string serverPort = "8000";
string secret = "test";
_datagramSocket = new DatagramSocket();
_datagramSocket.MessageReceived += (s, e) =>
{
DataReader dataReader = e.GetDataReader();
if (dataReader.UnconsumedBufferLength > 0 && dataReader.ReadByte() == 0)
{
var parameters = dataReader.ReadString(dataReader.UnconsumedBufferLength);
ConfigureAndConnect(channel, parameters);
}
};
var serverHostName = channel.Configuration.ServerHostNameList[0];
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(channel.Configuration.CustomField);
var firstChild = xmlDocument.FirstChild;
if (firstChild.Name.Equals("ToyVpnConfig"))
{
foreach (XmlNode childNode in firstChild.ChildNodes)
{
if (childNode.Name.Equals("ServerPort")) serverPort = childNode.InnerText;
else if (childNode.Name.Equals("Secret")) secret = childNode.InnerText;
}
}
await _datagramSocket.ConnectAsync(serverHostName, serverPort);
await HandShake(_datagramSocket, secret);
}
public void Disconnect(VpnChannel channel)
{
channel.Stop();
}
public void GetKeepAlivePayload(VpnChannel channel, out VpnPacketBuffer keepAlivePacket)
{
keepAlivePacket = null;
}
public void Encapsulate(VpnChannel channel, VpnPacketBufferList packets, VpnPacketBufferList encapulatedPackets)
{
while (packets.Size > 0)
{
VpnPacketBuffer vpnPacketBuffer = packets.RemoveAtBegin();
var buffer = vpnPacketBuffer.Buffer;
VpnPacketBufferStatus vpnPacketBufferStatus = vpnPacketBuffer.Status;
encapulatedPackets.Append(vpnPacketBuffer);
}
}
public void Decapsulate(VpnChannel channel, VpnPacketBuffer encapBuffer, VpnPacketBufferList decapsulatedPackets, VpnPacketBufferList controlPacketsToSend)
{
while (encapBuffer != null)
{
decapsulatedPackets.Append(encapBuffer);
}
}
async Task HandShake(DatagramSocket datagramSocket, string secret)
{
for (int i = 0; i < 3; i++)
{
var dataWriter = new DataWriter(datagramSocket.OutputStream)
{
UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8
};
dataWriter.WriteByte(0);
dataWriter.WriteString(secret);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
}
void ConfigureAndConnect(VpnChannel vpnChannel, string parameters)
{
parameters = parameters.TrimEnd();
uint mtu = 1500;
List<HostName> ipv4InclusionHostNames = new List<HostName>();
List<HostName> dnsServerHostNames = new List<HostName>();
VpnRouteAssignment vpnRouteAssignment = new VpnRouteAssignment();
var ipv4InclusionRoutes = vpnRouteAssignment.Ipv4InclusionRoutes;
foreach (var parameter in parameters.Split(null))
{
var fields = parameter.Split(",");
try
{
switch (fields[0])
{
case "m":
mtu = uint.Parse(fields[1]);
break;
case "a":
ipv4InclusionHostNames.Add(new HostName(fields[1]));
break;
case "r":
ipv4InclusionRoutes.Add(new VpnRoute(new HostName(fields[1]), (byte)uint.Parse(fields[2])));
break;
case "d":
dnsServerHostNames.Add(new HostName(fields[1]));
break;
case "s":
//TODO "SearchDomain"
break;
default:
break;
}
}
catch (Exception)
{
throw;
}
}
VpnDomainNameAssignment vpnDomainNameAssignment = new VpnDomainNameAssignment();
vpnDomainNameAssignment.DomainNameList.Add(new VpnDomainNameInfo(".", VpnDomainNameType.Suffix, dnsServerHostNames, null));
try
{
vpnChannel.AssociateTransport(_datagramSocket, null);
vpnChannel.StartExistingTransports(ipv4InclusionHostNames, null, null, vpnRouteAssignment, vpnDomainNameAssignment, mtu, 65535, false);
}
catch (Exception e)
{
vpnChannel.TerminateConnection(e.Message);
}
}
}
This appears to be unconfirmed working, any better idea or suggestions are greatly appreciated as I figured this out by more or less "fishing"...:
namespace Background
{
public enum HandshakeState { Waiting, Received, Canceled };
public sealed class SecurepointVpnPlugin : IVpnPlugIn
{
DatagramSocket _datagramSocket;
HandshakeState _handshakeState;
public void Connect(VpnChannel channel)
{
string serverPort = "8000";
string secret = "test";
string parameters = null;
_datagramSocket = new DatagramSocket();
channel.AssociateTransport(_datagramSocket, null);
_datagramSocket.MessageReceived += (s, e) =>
{
DataReader dataReader = e.GetDataReader();
if (dataReader.UnconsumedBufferLength > 0 && dataReader.ReadByte() == 0)
{
parameters = dataReader.ReadString(dataReader.UnconsumedBufferLength);
_handshakeState = HandshakeState.Received;
}
};
var serverHostName = channel.Configuration.ServerHostNameList[0];
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(channel.Configuration.CustomField);
var firstChild = xmlDocument.FirstChild;
if (firstChild.Name.Equals("ToyVpnConfig"))
{
foreach (XmlNode childNode in firstChild.ChildNodes)
{
if (childNode.Name.Equals("ServerPort")) serverPort = childNode.InnerText;
else if (childNode.Name.Equals("Secret")) secret = childNode.InnerText;
}
}
_datagramSocket.ConnectAsync(serverHostName, serverPort).AsTask().GetAwaiter().GetResult();
_handshakeState = HandshakeState.Waiting;
HandShake(_datagramSocket, secret).AsTask().GetAwaiter().GetResult();
if (_handshakeState == HandshakeState.Received) ConfigureAndConnect(channel, parameters);
else channel.Stop();
}
public void Disconnect(VpnChannel channel)
{
channel.Stop();
}
public void GetKeepAlivePayload(VpnChannel channel, out VpnPacketBuffer keepAlivePacket)
{
keepAlivePacket = null;
}
public void Encapsulate(VpnChannel channel, VpnPacketBufferList packets, VpnPacketBufferList encapulatedPackets)
{
while (packets.Size > 0) encapulatedPackets.Append(packets.RemoveAtBegin());
}
public void Decapsulate(VpnChannel channel, VpnPacketBuffer encapBuffer, VpnPacketBufferList decapsulatedPackets, VpnPacketBufferList controlPacketsToSend)
{
decapsulatedPackets.Append(encapBuffer);
}
IAsyncAction HandShake(DatagramSocket datagramSocket, string secret)
{
return Task.Run(async () =>
{
for (int i = 0; i < 3; i++)
{
var dataWriter = new DataWriter(datagramSocket.OutputStream)
{
UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8
};
dataWriter.WriteByte(0);
dataWriter.WriteString(secret);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
for (int i = 0; i < 50; i++)
{
await Task.Delay(100);
switch (_handshakeState)
{
case HandshakeState.Waiting:
break;
case HandshakeState.Received:
return;
case HandshakeState.Canceled:
throw new OperationCanceledException();
default:
break;
}
}
}).AsAsyncAction();
}
void ConfigureAndConnect(VpnChannel vpnChannel, string parameters)
{
parameters = parameters.TrimEnd();
uint mtuSize = 68;
var assignedClientIPv4list = new List<HostName>();
var dnsServerList = new List<HostName>();
VpnRouteAssignment assignedRoutes = new VpnRouteAssignment();
VpnDomainNameAssignment assignedDomainName = new VpnDomainNameAssignment();
var ipv4InclusionRoutes = assignedRoutes.Ipv4InclusionRoutes;
foreach (var parameter in parameters.Split(null))
{
var fields = parameter.Split(",");
switch (fields[0])
{
case "m":
mtuSize = uint.Parse(fields[1]);
break;
case "a":
assignedClientIPv4list.Add(new HostName(fields[1]));
break;
case "r":
ipv4InclusionRoutes.Add(new VpnRoute(new HostName(fields[1]), (byte)(int.Parse(fields[2]))));
break;
case "d":
dnsServerList.Add(new HostName(fields[1]));
break;
default:
break;
}
}
assignedRoutes.Ipv4InclusionRoutes = ipv4InclusionRoutes;
assignedDomainName.DomainNameList.Add(new VpnDomainNameInfo(".", VpnDomainNameType.Suffix, dnsServerList, null));
try
{
vpnChannel.StartExistingTransports(assignedClientIPv4list, null, null, assignedRoutes, assignedDomainName, mtuSize, mtuSize + 18, false);
}
catch (Exception e)
{
vpnChannel.TerminateConnection(e.Message);
}
}
}
}
Related
I am having problems updating a ListView on C# WinForm. The application is a test harness which connects to a TCP Server and receives a data stream. The test harness will then be used to create multiple connections to the server to do load testing. Each task is started using the following command where the number of task is entered on the form:
for (int i = 0; i < noTasks; i++)
{
bool saveAudio = noTasksCheckedListBox.GetItemCheckState(i) == CheckState.Checked; // true : false;
taskArray[i] = Task.Run(() => SendMessage((initId + i).ToString(), saveAudio, audioServerIP));
}
The SendMessage function creates the TCP client connection and creates a AsyncCallBack to process the incoming stream.
void SendMessage(string id, bool saveWav, string serverIP)
{
TcpClient tcpclientAudio = new TcpClient();
string message = "GET /msg?id=" + id + "&type=0 HTTP/1.1\r\n";
NetworkObject audioObj = new NetworkObject
{
tcp = tcpclientAudio,
ConnectionType = FileType.Audio,
URL = message
};
if (saveWav)
{
tcpclientAudio.BeginConnect(IPAddress.Parse(serverIP), 8008, new AsyncCallback(CallBackConnectMethod01), audioObj);
}
else
{
tcpclientAudio.BeginConnect(IPAddress.Parse(serverIP), 8008, new AsyncCallback(CallBackConnectMethod02), audioObj);
}
}
The only difference between the CallBackConnctMethod is that 02 save the data to a file.
void CallBackConnectMethod02(IAsyncResult result)
{
NetworkObject obj = (NetworkObject)result.AsyncState;
TcpClient tcp = obj.tcp;
NetworkStream ns = tcp.GetStream();
startedProcessCount++;
int thisTask = startedProcessCount;
byte[] buffer = new byte[2048];
string message = obj.URL;
byte[] request = Encoding.ASCII.GetBytes(message);
ns.Write(request, 0, request.Length);
ns.Read(buffer, 0, 1000);
RefreshTable(thisTask, "Incoming", null);
......
}
When debugging the app goes to the RefreshTable function a disappears when it goes in to the delegate section.
private void RefreshTable(int taskNo, string status, string misc)
{
if (this.tasksListView.InvokeRequired)
{
this.Invoke((MethodInvoker) delegate {
DateTime nowDateTime = DateTime.Now;
string now = nowDateTime.Year.ToString("D4") + nowDateTime.Month.ToString("D2") + nowDateTime.Day.ToString("D2") + "-" + nowDateTime.Hour.ToString("D2") + nowDateTime.Minute.ToString("D2") + nowDateTime.Second.ToString("D2");
string taskId = "Task-" + taskNo.ToString("D3");
if (status == "Incoming")
{
ListViewItem taskLVI = tasksListView.Items.Add(taskId);
taskLVI.SubItems.Add(now);
taskLVI.SubItems.Add(" ");
taskLVI.SubItems.Add(" ");
if (string.IsNullOrEmpty(misc))
taskLVI.SubItems.Add(" ");
else
taskLVI.SubItems.Add(misc);
taskLVI.SubItems.Add(" ");
}
else
{
switch (status)
{
case "Lost":
case "Completed":
case "Exception":
ListViewItem listViewItem = null;
for (int i = 0; i < tasksListView.Items.Count; i++)
{
if (tasksListView.Items[i].SubItems[0].Text == taskId)
{
listViewItem = tasksListView.Items[i];
break;
}
}
if (listViewItem != null)
ToListViewItem(listViewItem, status, misc, now);
break;
default:
break;
}
}
tasksListView.Refresh();
});
}
}
I've built a windows service that subscribes to around 10,000 stock tickers in real-time using ClientWebSocket. If I subscribe to 1,000 tickers I receive all the data points as I should (receiving few hundred messages a second), as soon as I get up to 2,000 tickers I don't seem to be receiving the data I should be, 10,000 (receiving thousands of messages a second) its even worse. I've run comparison reports and it looks like I'm losing up to 60% of the packets. I've talked to polygon (the provider of the real-time data) about this issue and they claim their Socket is a firehose and everything that should go out, goes out, and that none of their other clients are complaining. So the only logical thing here would to be to assume its my code, or some limitation. Maybe it's the Task portion of the Receive method? Maybe window's has a max task limitation and I'm exceeding it.
I've also tested this on a high powered dedicated server with 10gb connection so it doesnt seem to be a connection or hardware limitation.
I've also by passed my BlockingCollection cache and the problem still persisted.
Hopefully one of you has some insight, thank you!
Here's my code:
public static ConcurrentDictionary<string, TradeObj> TradeFeed = new ConcurrentDictionary<string, TradeObj>();
public static ConcurrentDictionary<string, QuoteObj> QuoteFeed = new ConcurrentDictionary<string, QuoteObj>();
public static ConcurrentDictionary<string, AggObj> AggFeed = new ConcurrentDictionary<string, AggObj>();
public static BlockingCollection<byte[]> packets = new BlockingCollection<byte[]>();
private static void Start(string[] args)
{
try
{
Polygon.StartSub();
int HowManyConsumers = 2;
for (int i = 0; i < HowManyConsumers; i++)
{
Task.Factory.StartNew(Polygon.ConsumePackets);
}
} catch(Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
public static async Task StartSub()
{
do
{
using (var socket = new ClientWebSocket())
try
{
// socket.Options.KeepAliveInterval = TimeSpan.Zero;
var Connection = "wss://socket.polygon.io/stocks";
await socket.ConnectAsync(new Uri(Connection), CancellationToken.None);
Console.WriteLine("Websocket opened to Polygon.");
await Send(socket, "{\"action\":\"auth\",\"params\":\""+ConfigurationManager.AppSettings["PolygonAPIToken"]+"\"}");
List<List<string>> batches = new List<List<string>>();
for (int i = 0; i < FeedCache.Tickers.Count(); i += 500)
{
var tempList = new List<string>();
tempList.AddRange(FeedCache.Tickers.Skip(i).Take(500));
batches.Add(tempList);
}
int bNum = 0;
string[] quoteStrings = new string[batches.Count()];
foreach (var tList in batches)
{
var tQuery = "";
tQuery = tQuery + "T." + string.Join(",T.", tList.ToArray());
tQuery = tQuery + ",A." + string.Join(",A.", tList.ToArray());
tQuery = tQuery + ",Q." + string.Join(",Q.", tList.ToArray());
quoteStrings[bNum] = tQuery;
bNum++;
}
for (int i = 0; i < quoteStrings.Count(); i++)
{
string SubscribeString = "{\"action\":\"subscribe\",\"params\":\"" + quoteStrings[i] + "\"}";
await Send(socket, SubscribeString);
}
await Receive(socket);
}
catch (Exception ex)
{
Console.WriteLine($"ERROR - {ex.Message}");
Console.WriteLine(ex.ToString());
}
} while (true);
}
static async Task Send(ClientWebSocket socket, string data)
{
var segment = new ArraySegment<byte>(Encoding.UTF8.GetBytes(data));
await socket.SendAsync(segment, WebSocketMessageType.Text, true, CancellationToken.None);
}
static async Task Receive(ClientWebSocket socket)
{
do {
WebSocketReceiveResult result;
var buffer = new ArraySegment<byte>(new byte[2000]);
using (var ms = new MemoryStream())
{
do
{
result = await socket.ReceiveAsync(buffer, CancellationToken.None);
ms.Write(buffer.Array, buffer.Offset, result.Count);
} while (!result.EndOfMessage);
if (result.MessageType == WebSocketMessageType.Close)
{
await socket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "Closed in server by the client", CancellationToken.None);
Console.WriteLine("Socket disconnecting, trying to reconnect.");
await StartSub();
}
else
{
packets.Add(ms.ToArray());
}
}
} while (true);
}
public static async void ConsumePackets()
{
foreach (var buffer in packets.GetConsumingEnumerable())
{
using (var ms = new MemoryStream(buffer))
{
ms.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(ms, Encoding.UTF8))
{
var data = await reader.ReadToEndAsync();
try
{
var j = JArray.Parse(data);
if (j != null)
{
string id = (string)j[0]["ev"];
switch (id)
{
case "T":
AddOrUpdateTrade((string)j[0]["sym"], j);
break;
case "Q":
AddOrUpdateQuote((string)j[0]["sym"], j);
break;
case "A":
AddOrUpdateAgg((string)j[0]["sym"], j);
break;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
}
public static void AddOrUpdateTrade(string ticker, JArray data)
{
TradeFeed.AddOrUpdate(ticker, new TradeObj {
LastPrice = (double)data[0]["p"],
TradeCount = 1
}, (key, existingVal) =>
{
return new TradeObj {
LastPrice = (double)data[0]["p"],
TradeCount = existingVal.TradeCount + 1,
PriceDirection = (double)data[0]["p"] < existingVal.LastPrice ? "D" : "U"
};
});
}
public static void AddOrUpdateAgg(string ticker, JArray data)
{
AggFeed.AddOrUpdate(ticker, new AggObj
{
TickVolume = (long)data[0]["v"],
VolumeShare = (long)data[0]["av"],
OpenPrice = (double)data[0]["op"],
TickAverage = (double)data[0]["a"],
VWAP = (double)data[0]["vw"],
TickClosePrice = (double)data[0]["c"],
TickHighPrice = (double)data[0]["h"],
TickLowPrice = (double)data[0]["l"],
TickOpenPrice = (double)data[0]["o"]
}, (key, existingVal) =>
{
return new AggObj
{
TickVolume = (long)data[0]["v"],
VolumeShare = (long)data[0]["av"],
OpenPrice = (double)data[0]["op"],
TickAverage = (double)data[0]["a"],
VWAP = (double)data[0]["vw"],
TickClosePrice = (double)data[0]["c"],
TickHighPrice = (double)data[0]["h"],
TickLowPrice = (double)data[0]["l"],
TickOpenPrice = (double)data[0]["o"]
};
});
}
public static void AddOrUpdateQuote(string ticker, JArray data)
{
QuoteFeed.AddOrUpdate(ticker, new QuoteObj
{
BidPrice = (double)data[0]["bp"],
BidSize = (double)data[0]["bs"],
AskPrice = (double)data[0]["ap"],
AskSize = (double)data[0]["as"]
}, (key, existingVal) =>
{
return new QuoteObj
{
BidPrice = (double)data[0]["bp"],
BidSize = (double)data[0]["bs"],
AskPrice = (double)data[0]["ap"],
AskSize = (double)data[0]["as"]
};
});
}
I am having trouble with system.outofmemoryexception on my C# win application. I don't know the cause of the error. The computer memory is not freeing.
I am using visual studio 2017 and devexpress 2017 with Firebird 3 as my database.
here is a sample of my database procedures
CREATE PROCEDURE APP_INSERT(
WORKXP_PK INTEGER,
EMP_PK INTEGER,
APP_FRONT BLOB,
APP_BACK BLOB,
USER_PK SMALLINT,
APP_UPDATETIME TIMESTAMP)
AS
BEGIN
INSERT INTO APPOINTMENT (
WORKXP_PK,
EMP_PK,
APP_FRONT,
APP_BACK,
USER_PK,
APP_UPDATETIME)
VALUES (
:WORKXP_PK,
:EMP_PK,
:APP_FRONT,
:APP_BACK,
:USER_PK,
CURRENT_TIMESTAMP);
END;
CREATE PROCEDURE APP_UPDATE(
APP_FRONT BLOB,
APP_BACK BLOB,
USER_PK SMALLINT,
APP_UPDATETIME TIMESTAMP,
WORKXP_PK INTEGER)
AS
BEGIN
UPDATE APPOINTMENT
SET
APP_FRONT = :APP_FRONT,
APP_BACK = :APP_BACK,
USER_PK = :USER_PK,
APP_UPDATETIME = CURRENT_TIMESTAMP
WHERE
(WORKXP_PK = :WORKXP_PK);
END;
And here is a sample of my c# class
using DevExpress.XtraEditors;
using FirebirdSql.Data.FirebirdClient;
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;
namespace DepEdZDSMS.Class
{
class ClsAppointmntPic : IDisposable
{
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
FirebirdService.Close();
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public MemoryStream APP_FRONT { get; set; }
public MemoryStream APP_BACK { get; set; }
public void UpdateAppImage()
{
byte[] x = null; //front image
byte[] y = null; //back image
try
{
var adder = new FbConnection(ClsConnectionImages.FirebirdSQL);
var fbcmd = new FbCommand("APP_UPDATE", adder)
{
CommandType = CommandType.StoredProcedure
};
if (APP_FRONT != null) x = APP_FRONT.ToArray();
fbcmd.Parameters.Add("#APP_FRONT", FbDbType.Binary).Value = x;
if (APP_BACK != null) y = APP_BACK.ToArray();
fbcmd.Parameters.Add("#APP_BACK", FbDbType.Binary).Value = y;
fbcmd.Parameters.Add("#USER_PK", FbDbType.SmallInt).Value = ClsEmployee.USER_PK;
fbcmd.Parameters.Add("#APP_UPDATETIME", FbDbType.VarChar).Value = EventTimestamp;
fbcmd.Parameters.Add("#WORKXP_PK", FbDbType.VarChar).Value = ClsEmployee.UpdateHandler2;
fbcmd.Connection.Open();
fbcmd.ExecuteNonQuery();
fbcmd.Connection.Close();
}
catch (Exception errorcode)
{
XtraMessageBox.Show(String.Format("Error in connection: {0}. Saving failed.", errorcode.Message), #"Server Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
public void SaveAppImage() //122
{
byte[] x = null; //front image
byte[] y = null; //back image
try
{
var adder = new FbConnection(ClsConnectionImages.FirebirdSQL);
var fbcmd = new FbCommand("APP_INSERT", adder)
{
CommandType = CommandType.StoredProcedure
};
fbcmd.Parameters.Add("#WORKXP_PK", FbDbType.VarChar).Value = ClsEmployee.UpdateHandler2;
fbcmd.Parameters.Add("#EMP_PK", FbDbType.VarChar).Value = ClsEmployee.UpdateHandler;
if (APP_FRONT != null) x = APP_FRONT.ToArray();
fbcmd.Parameters.Add("#APP_FRONT", FbDbType.Binary).Value = x;
if (APP_BACK != null) y = APP_BACK.ToArray();
fbcmd.Parameters.Add("#APP_BACK", FbDbType.Binary).Value = y;
fbcmd.Parameters.Add("#USER_PK", FbDbType.SmallInt).Value = ClsEmployee.USER_PK;
fbcmd.Parameters.Add("#APP_UPDATETIME", FbDbType.VarChar).Value = EventTimestamp;
fbcmd.Connection.Open();
fbcmd.ExecuteNonQuery();
fbcmd.Connection.Close();
}
catch (Exception errorcode)
{
XtraMessageBox.Show(String.Format("Error in connection: {0}. Saving failed.", errorcode.Message), #"Server Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
public ClsAppointmntPic(int refID)
{
try
{
var app = new ClsAppointmntPic();
var x = new DataSet();
var y = new FbDataAdapter();
var f = new FbCommand("IMAGE_APPOINTMENT", FirebirdService);
f.Parameters.Add("#X", FbDbType.Integer).Value = refID;
f.CommandType = CommandType.StoredProcedure;
y.SelectCommand = f;
y.Fill(x, "APPOINTMENT");
if (x.Tables[0].Rows.Count > 0)
{
var fx = x.Tables[0].Rows[0];
if (!fx["APP_FRONT"].Equals(DBNull.Value))
{
var i = (byte[])fx["APP_FRONT"];
var fx2 = new MemoryStream(i);
APP_FRONT = fx2;
}
if (!fx["APP_BACK"].Equals(DBNull.Value))
{
var j = (byte[])fx["APP_BACK"];
var fx2 = new MemoryStream(j);
APP_BACK = fx2;
}
}
app.FirebirdService.Close();
}
catch (Exception e)
{
XtraMessageBox.Show(#"Error: " + e.Message, #"DepEdZDSUIS", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
public ClsAppointmntPic()
{
// TODO: Complete member initialization
}
private void Openconnection()
{
if (FirebirdService.State == ConnectionState.Open)
{
FirebirdService.Close();
}
FirebirdService.Open();
}
private void Closeconnection()
{
FirebirdService.Close();
}
private static readonly string Firebird = ClsConnectionImages.FirebirdSQL;
/// <summary>
///
/// </summary>
private readonly FbConnection FirebirdService = new FbConnection(Firebird);
}
}
and also I used public static string and int frequently and some arrays
public static int sdsapprove_ref = 0;
public static string sdsapprove_word = "";
public static string[] reasonReg = new string[] { "Deceased", "Promoted to", "Retired", "Resigned",
"Transferred to"};
in my main view form I use this code in displaying data
private void GetWorkXPList()
{
picAppFront.Image = Properties.Resources.no_image;
picAppBack.Image = Properties.Resources.no_image;
ClsEmployee.UpdateHandler2 = "0";
gridControl2.DataSource = ClsEmployee.WorkXP_SrvcRcrdListing();
gridView2.OptionsSelection.InvertSelection = false;
gridView2.OptionsSelection.EnableAppearanceFocusedCell = false;
gridView2.OptionsSelection.EnableAppearanceFocusedRow = true;
}
public void GetAppointmentImage()
{
int getID = Convert.ToInt32(ClsEmployee.UpdateHandler2);
var f = new ClsAppointmntPic(getID);
if (f.APP_FRONT != null)
{
var i = new Bitmap(f.APP_FRONT);
picAppFront.Image = i;
}
else
{
picAppFront.Image = Properties.Resources.no_image;
}
if (f.APP_BACK != null)
{
var j = new Bitmap(f.APP_BACK);
picAppBack.Image = j;
}
else
{
picAppBack.Image = Properties.Resources.no_image;
}
}
and in my save/update form, i use this codes when saving and editing
private void UpdateWorXP()
{
var adder = new ClsEmployee()
{
WORKXP_DATEFROM = dateFrom.Text,
WORKXP_DATETO = dateTo.Text,
WORKXP_PRESENT = ifPresent,
WORKXP_POSITION = txtPosition.Text,
WORKXP_ABBR = txtAbb.Text,
WORKXP_ITMENUM = txtItemNo.Text,
WORKXP_AGENCY = txtAgency.Text,
WORKXP_STATION = txtStation.Text,
WORKXP_BRANCH = txtBranch.Text,
WORKXP_SLRYGRD = txtSG.Text,
WORKXP_INCRMNT = cboxIncrmnt.Text,
WORKXP_SALARYANN = txtAnnual.Text,
WORKXP_SALARYMON = txtMonthly.Text,
WORKXP_STATUS = cboxStatus.Text,
WORKXP_GOVORPRIV = cboxGov.Text,
WORKXP_CAUSE = cboxCause.Text,
WORKXP_AMOUNT = Convert.ToDecimal(txtAmount.Text),
};
adder.EditWorkXP();
adder.UpdateLog();
//UpdateEmpLatestApp();
XtraMessageBox.Show("Successfully Updated.", "Update ",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
ClsEmployee.UpdateHandler2 = "0";
switch (ClsArray.Reference)
{
case 1:
obj1.loaddata();
break;
case 2:
obj2.loaddata();
break;
case 3:
obj3.loaddata2();
break;
}
this.Close();
}
private void AddNewWorkXP()
{
var adder = new ClsEmployee()
{
WORKXP_DATEFROM = dateFrom.Text,
WORKXP_DATETO = dateTo.Text,
WORKXP_PRESENT = ifPresent,
WORKXP_POSITION = txtPosition.Text,
WORKXP_ABBR = txtAbb.Text,
WORKXP_ITMENUM = txtItemNo.Text,
WORKXP_AGENCY = txtAgency.Text,
WORKXP_STATION = txtStation.Text,
WORKXP_BRANCH = txtBranch.Text,
WORKXP_SLRYGRD = txtSG.Text,
WORKXP_INCRMNT = cboxIncrmnt.Text,
WORKXP_SALARYANN = txtAnnual.Text,
WORKXP_SALARYMON = txtMonthly.Text,
WORKXP_STATUS = cboxStatus.Text,
WORKXP_GOVORPRIV = cboxGov.Text,
WORKXP_CAUSE = cboxCause.Text,
WORKXP_AMOUNT = Convert.ToDecimal(txtAmount.Text),
};
adder.SaveWorkXP();
adder.UpdateLog();
//UpdateEmpLatestApp();
XtraMessageBox.Show("Successfully Saved.", "Save ",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
ClsEmployee.UpdateHandler2 = "0";
switch (ClsArray.Reference)
{
case 1:
obj1.loaddata();
break;
case 2:
obj2.loaddata();
break;
case 3:
obj3.loaddata2();
break;
}
this.Close();
}
I read this article , I want to get sent bytes and receive bytes for all process, but sent bytes and receive bytes of all process always return 0;
Here is my code:
namespace Network
{
public class NetworkTraffic
{
private List<PerformanceCounter> listBytesSentPerformanceCounter;
private List<PerformanceCounter> listBytesReceivedPerformanceCounter;
//private PerformanceCounter bytesSentPerformanceCounter;
//private PerformanceCounter bytesReceivedPerformanceCounter;
public NetworkTraffic()
{
listBytesSentPerformanceCounter = new List<PerformanceCounter>();
listBytesReceivedPerformanceCounter = new List<PerformanceCounter>();
List<string> listInstanceName = GetInstanceName();
foreach (string str in listInstanceName)
{
PerformanceCounter bytesSentPerformanceCounter = new PerformanceCounter();
PerformanceCounter bytesReceivedPerformanceCounter = new PerformanceCounter();
bytesSentPerformanceCounter.CategoryName = ".NET CLR Networking 4.0.0.0";
bytesSentPerformanceCounter.CounterName = "Bytes Sent";
bytesSentPerformanceCounter.InstanceName = str;
bytesSentPerformanceCounter.ReadOnly = false;
listBytesSentPerformanceCounter.Add(bytesSentPerformanceCounter);
bytesReceivedPerformanceCounter.CategoryName = ".NET CLR Networking 4.0.0.0";
bytesReceivedPerformanceCounter.CounterName = "Bytes Received";
bytesReceivedPerformanceCounter.InstanceName = str;
bytesReceivedPerformanceCounter.ReadOnly = false;
listBytesReceivedPerformanceCounter.Add(bytesReceivedPerformanceCounter);
}
}
//public float GetBytesSent()
//{
// float bytesSent = bytesSentPerformanceCounter.RawValue;
// return bytesSent;
//}
//public float GetBytesReceived()
//{
// float bytesReceived = bytesReceivedPerformanceCounter.RawValue;
// return bytesReceived;
//}
private static List<string> GetInstanceName()
{
// Used Reflector to find the correct formatting:
string assemblyName = GetAssemblyName();
if ((assemblyName == null) || (assemblyName.Length == 0))
{
assemblyName = AppDomain.CurrentDomain.FriendlyName;
}
StringBuilder builder = new StringBuilder(assemblyName);
for (int i = 0; i < builder.Length; i++)
{
switch (builder[i])
{
case '/':
case '\\':
case '#':
builder[i] = '_';
break;
case '(':
builder[i] = '[';
break;
case ')':
builder[i] = ']';
break;
}
}
List<string> listInstanceName = new List<string>();
Process[] listProcess = Process.GetProcesses();
string InstanceName;
foreach (Process pro in listProcess)
{
InstanceName = string.Format(CultureInfo.CurrentCulture,
"{0}[{1}]",
builder.ToString(),
pro.Id);
listInstanceName.Add(InstanceName);
}
return listInstanceName;
}
private static string GetAssemblyName()
{
string str = null;
Assembly entryAssembly = Assembly.GetEntryAssembly();
if (entryAssembly != null)
{
AssemblyName name = entryAssembly.GetName();
if (name != null)
{
str = name.Name;
}
}
return str;
}
public static void Main()
{
NetworkTraffic networkTraffic = new NetworkTraffic();
try
{
while (true)
{
WebRequest webRequest = WebRequest.Create("http://www.google.com");
webRequest.Method = "GET";
using (WebResponse response = webRequest.GetResponse())
using (Stream responseStream = response.GetResponseStream())
using (StreamReader reader = new StreamReader(responseStream))
{
}
//Console.WriteLine("Bytes sent: {0}", networkTraffic.GetBytesSent());
//Console.WriteLine("Bytes received: {0}", networkTraffic.GetBytesReceived());
foreach (PerformanceCounter send in networkTraffic.listBytesSentPerformanceCounter)
{
Console.WriteLine("Instance name: " + send.InstanceName + " Sent: " + send.RawValue);
}
Thread.Sleep(1000);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadLine();
}
}
}
Anyone can help me resolve this.
For load testing purposes I need to simulate multiple users trying to login to a system at the same time. I have code written by another developer that can send a login request to the system. With an ok login it will also return other information in xml.
I've tried using Parallel.ForEach, but dont have any real experience with parallel programming:
Parallel.ForEach(clientList, client =>
{
RunTest(client);
});
public void RunTest(object data)
{
if (!(data is IGprsClient))
{
return;
}
_noRunningTests += 1;
IGprsClient gprsClient = data as IGprsClient;
DateTime startTime = DateTime.Now;
Log(gprsClient.Id, "Test started.");
bool result = gprsClient.StartTest(20000);
DateTime endTime = DateTime.Now;
TimeSpan diff = endTime - startTime;
if (result == false)
{
Log(gprsClient.Id, "Test failed.");
}
Log(gprsClient.Id, "Test took {0}ms. ", (int)diff.TotalMilliseconds);
_noRunningTests -= 1;
}
override public bool StartTest(int timeout)
{
_testStarted = true;
try
{
LogDebug("Trying to connect.");
_client = new TcpClient(ipAddress, port);
LogDebug("Connected.");
bool result = false;
//Todo: insert testcase into client
switch (TestCaseName)
{
case "LoginTEST":
var testCase = new LoginTEST(this);
result = testCase.Execute(user, pwd, phoneNum);
break;
default:
Log("Unknown test case: " + TestCaseName);
break;
}
_client.Close();
return result;
}
catch (Exception ex)
{
if (_client != null)
_client.Close();
Log(ex.Message);
return false;
}
}
Which in turn will send the request and read the response.
public bool Execute(string user, string pwd, string phoneNum)
{
SendDataListRequest(userId);
string requiredDataResponse = Client.ReadMsg();
return true;
}
Run test will send a request and reads the message like so:
public string ReadMsg()
{
int msgLength = -1;
var stream = _client.GetStream();
while (_testStarted)
{
int b = stream.ReadByte();
if (b == -1)
{
return "";
}
else if (b == 0x02 || msgLength == -1)
{
while (b != 0x02 && _testStarted)
{
b = stream.ReadByte(); // Finds the start token
if (b == -1)
{
return "";
}
}
msgLength = 0; // Starts collecting data
}
else if (b == 0x03)
{
byte[] encryptedMsg = Convert.FromBase64String(
Encoding.UTF8.GetString(byteBuffer, 0, msgLength));
byte[] decryptedMsg = SttCipher.DecryptMessage(encryptedMsg);
MemoryStream ms = new MemoryStream(decryptedMsg);
GZipStream gZipStream = new GZipStream(ms, CompressionMode.Decompress, true);
var bufLen = ReadAllBytesFromStream(gZipStream, decompressedBuffer);
gZipStream.Close();
string completeMsg = Encoding.UTF8.GetString(decompressedBuffer, 0, bufLen);
if (completeMsg.Length < 500)
LogDebug("Received XML-data:\n{0}", completeMsg);
else
LogDebug("Received XML-data: {0} bytes\n{1}...", completeMsg.Length, completeMsg.Substring(0, 500));
return completeMsg;
}
else
{
if (byteBuffer.Length <= msgLength)
{
throw new Exception("XML message too long!");
}
byteBuffer[msgLength] = (byte)b;
msgLength++;
}
}
return "";
}
Running one client is fine and will wait for the response. The issue is with several clients, the responses gets cut off. Leaving me with unclosed xml in the response.But I cant't figure out why. Does anyone have a reasonable explanation and/or a solution or a better way of doing it?