I am using the remoteAppender inside of the config file and sending the logs remotely to another computer. While sending the information using tcp worked, I found that the remoteAppender was also sending a large chunk of random symbols and characters rather then the log string I want. I suspect that what is being sent by the remoteAppender is not a log string, but rather the logger itself. The method I used to read in the incoming broadcast is simple and taken from the msdm website. Does anyone know of a way to convert the networkstream received back into a string and avoiding all the strange outputs?
public void StartListener()
{
try
{
// Set the TcpListener on port 13000.
Int32 port = 32100;
// TcpListener server = new TcpListener(port);
server = new TcpListener(IPAddress.Any, port);
// Start listening for client requests.
server.Start();
// Buffer for reading data
Byte[] bytes = new Byte[256];
String data = null;
// Enter the listening loop.
while (true)
{
Console.Write("Waiting for a connection... ");
// Perform a blocking call to accept requests.
// You could also user server.AcceptSocket() here.
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
data = null;
// Get a stream object for reading and writing
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.UTF8.GetString(bytes, 0, i);
Console.WriteLine("Received: {0}", data);
// Process the data sent by the client.
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
// Send back a response.
stream.Write(msg, 0, msg.Length);
Console.WriteLine("Sent: {0}", data);
}
// Shutdown and end connection
client.Close();
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
catch (Exception e)
{
Console.WriteLine("Connection was terminated");
}
finally
{
// Stop listening for new clients.
server.Stop();
}
Console.WriteLine("\nHit enter to continue...");
Console.Read();
}
here is the output I got when I was sent a log via the remoteAppender:
Waiting for a connection... Connected!
Received: .NET☺ /♥ ♦ ☺☺$ tcp://149.63.90.84:32100/LoggingSink♠ ☺☺↑ appl
ication/octet-stream
Sent: .NET☺ /♥ ♦ ☺☺$ TCP://149.63.90.84:32100/LOGGINGSINK♠ ☺☺↑ APPLICAT
ION/OCTET-STREAM
Received: ☺ ????☺ §¶ ↕ LogEvents↕?☺log4net.Appender.RemotingApp
ender+IRemoteLoggingSink, log4net, Version=1.2.11.0, Culture=neutral, PublicKeyT
oken=669e0ddf0bb1aa2a►☺ ☺ ☻ ♀♥ Klog4net, Version=1.2.11.0, Culture=neu
tral, PublicKeyToken=669e0ddf0bb1
Sent: ☺ ????☺ §¶ ↕ LOGEVENTS↕?☺LOG4NET.APPENDER.REMOTINGAPPENDER+IR
EMOTELOGGINGSINK, LOG4NET, VERSION=1.2.11.0, CULTURE=NEUTRAL, PUBLICKEYTOKEN=669
E0DDF0BB1AA2A►☺ ☺ ☻ ♀♥ KLOG4NET, VERSION=1.2.11.0, CULTURE=NEUTRAL, PU
BLICKEYTOKEN=669E0DDF0BB1
Received: aa2a☻ ☺ ☺ ♦↓log4net.Core.LoggingEvent♥ ♦ ♣♦ ↓log4ne
t.Core.LoggingEvent♂
LoggerName♣LevelMessage
ThreadName TimeStamp♀LocationInfUserName☼ExceptionString
!log4net.Util.Propertity☺♦☺☺ ☻☻☺♦☺☻↕log4net.Core.Level♥
Sent: AA2A☻ ☺ ☺ ♦↓LOG4NET.CORE.LOGGINGEVENT♥ ♦ ♣♦ ↓LOG4NET.CORE.L
OGGINGEVENT♂
LOGGERNAME♣LEVELMESSAGE
THREADNAME TIMESTAMP♀LOCATIONINFUSERNAME☼EXCEPTIONSTRING
!LOG4NET.UTIL.PROPERTITY☺♦☺☺ ☻☻☺♦☺☻↕LOG4NET.CORE.LEVEL♥
Received: iesDictionary♥ ♥ ♠♣ ►Project2.Program ♠ ♠ ♥Hi0 ♦6384?:??
Uf?
♠
♠♂ ‼Project2.vshost.exe
♣♠ ↕log4net.Core.Level♥ ♀m_levelValue♂m_levelName↕m_levelDisplayName ♥ p◄☺
♠♀ ♣ERROR ♀ ♣
!log4net.Util.PropertiesDictionary☺
Sent: IESDICTIONARY♥ ♥ ♠♣ ►PROJECT2.PROGRAM ♠ ♠ ♥HI0 ♦6384?:??
UF?
♠
♠♂ ‼PROJECT2.VSHOST.EXE
♣♠ ↕LOG4NET.CORE.LEVEL♥ ♀M_LEVELVALUE♂M_LEVELNAME↕M_LEVELDISPLAYNAME ♥ P◄☺
♠♀ ♣ERROR ♀ ♣
!LOG4NET.UTIL.PROPERTIESDICTIONARY☺
♂KOLLIK-D1SD♂net_x003A_HostName☺♥ ♠
♂KOLLIK-D1SD♂X003A_HOSTNAME☺♥ ♠
The RemotingAppender uses .NET remoting to proxy log events to an endpoint that implement the log4net.Appender.RemotingAppender+IRemoteLoggingSink interface. It looks like you're trying to simply read the rendered log message via TCP, which is "working" except that, as you point out, your data stream does not contain rendered log strings but remoted binary log events.
Try the TelnetAppender or UDPAppender instead; these appenders render the log message before sending it over the network, so you'll get the string you expect.
See http://logging.apache.org/log4net/release/sdk/log4net.Appender.TelnetAppender.html
and http://maddemcode.com/net/secrets-of-log4net-telnetappender/
Related
From TCP based environment, I implement my software like below,
Actually, it's my first time implementing a network, so I don't know if this is the right way.
When the client connects, the server creates two threads. (Such as send, recv)
Send thread sends data when data enters the queue, and waits if it is empty.
Recv thread continuously receives and processes messages (ex. settings) sent by the client.
Currently, the total number of clients I am targeting is 4~5.
This is my sample code,
////////////////////////
// Send Thread
while(m_thread_stop_send == false) { // thread stop flag (when it terminated)
if(m_sendQueue.empty()) // Queue is memeber variable
continue;
// Send data to client
// until the size of MSG is completely transmitted.
while(send size < message size) {
int ret = send(... );
send size += ret;
...
if(send size == message size) break;
}
// (depending on the MSG) if necessary,
// Heres recv routine only treat send's ack
while(recv size < message size) { // according to packet header
int ret = recv(... );
recv size += ret;
...
if(recv size == message size) break;
}
m_sendQueue.pop();
}
////////////////////////
// Recv Thread
while(m_thread_stop_recv == false) { // thread stop flag (when it terminated)
if(alive_flag > 5) // if no alive Msg while 25 sec,
close socket;
terminate recv thread
notify to termination to send thread
// recv client's message and parsing OP-Code
switch(OP-Code)
{
case A:
processing...
and send response to client
// response was sent directly, without send queue & thread
send(... response data ...);
case B:
processing...
and send response to client
case Alive: // 5 sec term
alive_flag = 0
}
}
So I try to these code, but I'm not sure this is correct way ...
Do you have any good examples or open sources of handling Send and Recv continuously, and for each client?
I am pretty new to Node.Js and I'm using tcp sockets to communicate with a client. Since the received data is fragmented I noticed that it prints "ondata" to the console more than once. I need to be able to read all the data and concatenate it in order to implement the other functions. I read the following http://blog.nodejs.org/2012/12/20/streams2/ and thought I can use socket.on('end',...) for this purpose. But it never prints "end" to the console.
Here is my code:
Client.prototype.send = function send(req, cb) {
var self = this;
var buffer = protocol.encodeRequest(req);
var header = new Buffer(16);
var packet = Buffer.concat([ header, buffer ], 16 + buffer.length);
function cleanup() {
self.socket.removeListener('data', ondata);
self.socket.removeListener('error', onerror);
}
var body = '';
function ondata() {
var chunk = this.read() || '';
body += chunk;
console.log('ondata');
}
self.socket.on('readable', ondata);
self.socket.on('end', function() {
console.log('end');
});
function onerror(err) {
cleanup();
cb(err);
}
self.socket.on('error', onerror);
self.socket.write(packet);
};
The end event will handle the FIN package of the TCP protocol (in other words: will handle the close package)
Event: 'end'#
Emitted when the other end of the socket sends a FIN packet.
By default (allowHalfOpen == false) the socket will destroy its file descriptor once it has written out its pending write queue. However, by setting allowHalfOpen == true the socket will not automatically end() its side allowing the user to write arbitrary amounts of data, with the caveat that the user is required to end() their side now.
About FIN package: https://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_termination
The solution
I understand your problem, the network communication have some data transfer gaps and it split your message in some packages. You just want read your fully content.
For solve this problem i will recommend you create a protocol. Just send a number with the size of your message before and while the size of your concatenated message was less than total of your message size, keep concatenating :)
I have created a lib yesterday to simplify that issue: https://www.npmjs.com/package/node-easysocket
I hope it helps :)
Im working on a project with an Arduino and Ethernet Shield.
I would like to execute a php script (residing on my server) in the loop.
#include <SPI.h>
#include <Ethernet.h>
// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,77); // IP address, may need to change depending on network
EthernetServer server(80); // create a server at port 80
String HTTP_req; // stores the HTTP request
void setup()
{
Ethernet.begin(mac, ip); // initialize Ethernet device
server.begin(); // start to listen for clients
Serial.begin(9600); // for diagnostics
}
void loop()
{
EthernetClient client = server.available(); // try to get client
if (client) { // got client?
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) { // client data available to read
char c = client.read(); // read 1 byte (character) from client
HTTP_req += c; // save the HTTP request 1 char at a time
Serial.print("connected");
client.println("GET http://domain.com/arduino/scripts/script_motion_detection_driveway.php HTTP/1.0");
client.println();
} // end if (client.available())
} // end while (client.connected())
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection
} // end if (client)
}
When I run the code and load the page, instead of executing the script it just prints the line:
GET http://domain.com/arduino/scripts/script_motion_detection_driveway.php HTTP/1.0
over and over again...
The reason its in the loop as opposed to setup is because eventually the GET request will be placed inside an if statement to test a condition.
What do I need to change to execute the script?
You should check this example: http://www.arduino.cc/en/Tutorial/WebClient
You want to execute a GET request without telling the client to connect to the server at the port 80.
if (client.connect(server, 80)) {
Then you make your http request
// Make a HTTP request:
client.println("GET /search?q=arduino HTTP/1.1");
client.println("Host: www.google.com");
client.println("Connection: close");
client.println();
Then you try to read the request
if (client.available()) {
char c = client.read();
Serial.print(c);
}
By putting these parts together in a better way than your script above, you will successfully get the output of your php script.
I have a client application that receives video stream from a server via UDP or TCP socket.
Originally, when it was written using .NET 2.0 the code was using BeginReceive/EndReceive and IAsyncResult.
The client displays each video in it's own window and also using it's own thread for communicating with the server.
However, since the client is supposed to be up for a long period of time, and there might be 64 video streams simultaneously, there is a "memory leak" of IAsyncResult objects that are allocated each time the data receive callback is called.
This causes the application eventually to run out of memory, because the GC can't handle releasing of the blocks in time. I verified this using VS 2010 Performance Analyzer.
So I modified the code to use SocketAsyncEventArgs and ReceiveFromAsync (UDP case).
However, I still see a growth in memory blocks at:
System.Net.Sockets.Socket.ReceiveFromAsync(class System.Net.Sockets.SocketAsyncEventArgs)
I've read all the samples and posts about implementing the code, and still no solution.
Here's how my code looks like:
// class data members
private byte[] m_Buffer = new byte[UInt16.MaxValue];
private SocketAsyncEventArgs m_ReadEventArgs = null;
private IPEndPoint m_EndPoint; // local endpoint from the caller
Initializing:
m_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_Socket.Bind(m_EndPoint);
m_Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer, MAX_SOCKET_RECV_BUFFER);
//
// initalize the socket event args structure.
//
m_ReadEventArgs = new SocketAsyncEventArgs();
m_ReadEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(readEventArgs_Completed);
m_ReadEventArgs.SetBuffer(m_Buffer, 0, m_Buffer.Length);
m_ReadEventArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
m_ReadEventArgs.AcceptSocket = m_Socket;
Starting the read process:
bool waitForEvent = m_Socket.ReceiveFromAsync(m_ReadEventArgs);
if (!waitForEvent)
{
readEventArgs_Completed(this, m_ReadEventArgs);
}
Read completion handler:
private void readEventArgs_Completed(object sender, SocketAsyncEventArgs e)
{
if (e.BytesTransferred == 0 || e.SocketError != SocketError.Success)
{
//
// we got error on the socket or connection was closed
//
Close();
return;
}
try
{
// try to process a new video frame if enough data was read
base.ProcessPacket(m_Buffer, e.Offset, e.BytesTransferred);
}
catch (Exception ex)
{
// log and error
}
bool willRaiseEvent = m_Socket.ReceiveFromAsync(e);
if (!willRaiseEvent)
{
readEventArgs_Completed(this, e);
}
}
Basically the code works fine and I see the video streams perfectly, but this leak is a real pain.
Did I miss anything???
Many thanks!!!
Instead of recursively calling readEventArgs_Completed after !willRaiseEvent use goto to return to the top of the method. I noticed I was slowly chewing up stack space when I had a pattern similar to yours.
I am trying to create a simple reply server in node.js
The problem I am having, is that when I telnet into the server, and send a hello, the if loop doesn't catch it, and it goes to the else.
Below is my code:
var net = require('net');
var server = net.createServer(function(socket) {
// Server start
socket.write('Welcome\n');
socket.on('data', function(data) {
dataReceived(socket, data);
});
});
server.listen(8250);
function dataReceived(socket, data) {
if(data == 'hello') {
socket.end('Hi');
} else {
socket.write(data);
socket.end('what??\n');
}
}
Thanks.
Data is a binary buffer, not a string. See http://nodejs.org/docs/v0.4.9/api/buffers.html.
Use the buffer.toString method to convert to a string.
Also, a new line will be added when hitting enter in telnet. Not sure if line endings vary by os, but in this case I'm stripping \r\n.
function dataReceived(socket, data) {
data = data.toString('utf8').replace(/\r\n/, '');
if(data == 'hello') {
socket.end('Hi');
} else {
socket.write(data);
socket.end('what??\n');
}
}
As mentioned, main problem is that you compare Buffer object with string.
There is another problem, most probably not visible in your example.
You don't have control how data is split into packets. 'Hello' sent to your server may result dataReceived called with 'Hel' + 'l' + 'o' buffer 3 times
Correct way to handle 'Hello' input us to create state machine or, more simple and less efficient - buffer all incoming data, look for 'Hello' at the beginning of buffered data, then cut handled data from buffer. There are modules aiming to help to unpack/unframe structured data from input stream, for example node-binary