Use socket from C# in C++ - c#

I am trying to port my server code from Linux to Windows, so I thought that easiest way would be to write a wrapper in C#.
Basically, what I would C# would do is:
C# loads Server.dll written entirely in C++ containing functions:
InsertClient(sockId)
DisconnectClient(sockId)
ProcessResponse(sockId,len,buffer)
C# creates basic server bound to port N on TCP.
When C# server accepts new client and gets Socket struct as return, it must call DLL function InsertClient(sockId)
When C# server receives some data from the client, it sends it again to DLL function ProcessResponse(sockId,len,data)
While data are processed all the time in Server.dll and some event happens, Server.dll would send response back to client using the only available function in C++ for sending data: send(sockId,buffer,len,flags)
But here it comes to the problem, at point 5, I need to already use socket ID, because without it I can't use send(...) , so what I could do is:
Server.dll would invoke call back to main C# application to some somehow exported function, like SendPacket containing pointer to Socket struct, which I absolutely don't know if it's possible without using thousands of other framework go arounds.
In C# I would somehow get to the Socket ID from Socket struct, and send it to C++, so C++ can use it for simple send(...)

Related

Is it possible to create C# client to connect to a specific JVM-based server (Netty)?

I am working on a C# client for a server that wraps Netty. It is a TCP/IP server and I have tried using C# class TcpClient, but could not write anything onto the server or receive a printed response.
The Netty socket classes include the following: http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/socket/nio/NioClientSocketChannelFactory.html http://docs.jboss.org/netty/3.2/api/org/jboss/netty/bootstrap/ClientBootstrap.html
The message is encoded as a byte[] in Java. Part of class PingSerializer, in the server code, reads as follows:
public byte[] requestToBytes(Ping message) {
return NorbertExampleProtos.Ping.newBuilder().setTimestamp(message.timestamp).build().toByteArray();
}
public Ping requestFromBytes(byte[] bytes) {
try {
return new Ping(NorbertExampleProtos.Ping.newBuilder().mergeFrom(bytes).build().getTimestamp());
} catch (InvalidProtocolBufferException e) {
System.out.println("Invalid protocol buffer exception " + e.getMessage());
throw new IllegalArgumentException(e);
}
}
I would like to know whether it is possible for a client written in C# to connect to the socket, ping the server and print out the server's response, without modifying the server code or using a cross-language development tool such as Apache Thrift or IKVM to handle the messages. Thanks, I would appreciate any help.
Judging by the code sample you've given, it looks like the data is encoded using Protocol Buffers, Google's serialization format.
Fortunately, there are at least two libraries implementing Protocol Buffers for .NET:
protobuf-net: Written for .NET from the ground up, this is a good choice if you don't particularly need the C# code to look like the equivalent Java/C++ code.
protobuf-csharp-port: This is a port from the Java client code, with some .NET idioms added - so if you're working with Protocol Buffers on multiple platforms, this may be more appropriate. (Disclaimer: I did most of the coding for this port.)
The good news is that the wire format for the two is the same, because it's the standard Protocol Buffer wire format. So if you decide later on that you've made the wrong choice, you don't need to worry about the data format changing.
In terms of communicating with the server, TcpClient should be absolutely fine. You'll need to find out exactly what the protocol is - for example, whether it's Protocol Buffers over HTTP, or something similar. (If it is over HTTP, WebClient would be a simpler approach.) However, beyond that it's straight TCP/IP: you write the bytes to the server, and it should write a reply. You can use Wireshark to look at the traffic between the client and the server, if you need to trace where problems are occurring.
There is an application called CS2J that will convert all of your C# code directly over to Java. However, you cannot expect it to be perfect and you will have a bit of debugging to do. It is supposed to very accurate.

Interaction between MQL5 (or C++) and C# via Named Pipes

I am trying to send some data via Named Pipes. I created Named Pipe Server in C# and client in MQL5 (it is just a C++ wrapper). Server works fine and can be reached from Named Pipe Client written in C# so communication C# <-> C# works fine. Also i tried utility PipeList and it also shows that my pipe server is visible and available.
The only problem is with client written in MQL5 (C++) - it does not find the path to the pipe server so communication MQL <-> C# is failing.
Could anybody suggest :
what am i doing wrong?
how to check that both C# and MQL are accessing the same physical
path and the same location?
Server :
NamedPipeServerStream pipeStream = new NamedPipeServerStream("MQL5", PipeDirection.In, 1, PipeTransmissionMode.Byte)
I also tried full path \\\\.\\pipe\\MQL5 with no success
Client :
CFilePipe iPipe;
while(IsStopped() == false)
{
Print("This loop is infinite because there is no connection");
if (iPipe.Open("\\\\.\\pipe\\MQL5", FILE_READ | FILE_WRITE | FILE_BIN) != INVALID_HANDLE) break;
Sleep(250);
}
Thanks.
Answer is found. Seems that was simply my own mistake or this is how Pipes work in MQL - channel always needs to be Duplex so line in C# needs to be replaced with the following :
NamedPipeServerStream pipeStream = new NamedPipeServerStream(name, PipeDirection.InOut, 1, PipeTransmissionMode.Byte)
Parameter PipeDirection.InOut says pipe to be two-way.
P.S. Though it is a little weird anyway because conjunction C# Server <-> C# Client can work in both modes (In / Out or one of them)
Server: C# / Client: MetaTrader
I had two other problems:
The client and server needed to be run as Administrator
I needed to set buffer size for input and ouput (Default is zero =>
dynamically calculated => there was an error on this).

Modbus Custom Message & Sub functions (NModbus, TCP, Subfunctions)

I am using NModbus in a C# project, to read & write Modbus data from/to a number of I/O devices. I am using the Modbus TCP/IP protocol (ModbusIpMaster etc..) in the program.
I have successfully communicated with the devices (through a Modbus gateway) and can use the default methods (e.g. common Modbus functions such as ReadHoldingRegisters, WriteCoils ), to access the data from the devices, and can write back to them. At the moment, all I can do are the default NModbus methods which expose commonly used Modbus codes (1, 2, 3, 4 etc..).
I have two difficulties:
1) The I/O devices' settings and extra information can be accessed under the Modbus code of 70 (0x46), and there are sub functions which I will need to use in order to read and/or write the settings.
For example, Func 07 (0x46), Sub func 6 (0x06), can be used to set the communications settings of a module. In this example there are 7 bytes of information to be sent which carry the settings (e.g. baud rate etc...)
NModbus does not have a specific method for this 'custom' function code (70). So, from what I understand, one needs to use the CustomMessage feature of NModbus. I have tried executing CustomMessage, and when using the common Modbus function codes (e.g. 1 or 2) I can achieve the same result as if I were using the default methods of NModbus (i.e. the CustomMessage is working so far).
When I try function codes other than the general ones (e.g. 1, 2, 3...) I do get all sorts of exceptions. Furthermore, I do not know how I should send the sub-function with the message!
When I added the subfunction just after the function code (e.g. 70 followed by 06), and the data is send through I get, exceptions. I really need help from experts in this field, please.
Here is a more obvious exception:
" Exception of type 'Modbus.SlaveException' was thrown. Function Code: 198 Exception Code: 3 - A value contained in the query data
field is not an allowable value for server (or slave). This indicates
a fault in the structure of the remainder of a complex request, such
as that the implied length is incorrect. It specifically does NOT mean
that a data item submitted for storage in a register has a value
outside the expectation of the application program, since the MODBUS
protocol is unaware of the significance of any particular value of any
particular register."
2) The second problem is sending ASCII RS-232 messages through Modbus, in order to control an RS-232 device which is connected to COM1 of a module which has the ability to convert Modbus messages. In other words, I am planning to communicate with the Modbus gateway, to send ASCII data to its COM1, which in turn translates data to RS-232 and then communicates with the RS-232 device. The translation is meant to occur internal to the gateway, so all I need to know is how on Earth I can send these messages through, which vary in length. I have no idea how that is possible, and where to start from.
Part 2 - NModbus allows you to create an ASCII master over a TCP or UDP client.
using (TcpClient client = new TcpClient("127.0.0.1", 502))
{
ModbusSerialMaster master = ModbusSerialMaster.CreateAscii(client);
// Use the master here
}
With regard to the first part of the question, NModbus is great for the basics, but it lacks a layer of abstraction that would allow it to be extended arbitrarily. My own experience of it ended when I found that it would require significant modification to add and make the GetServerId function to work, even though this is part of the specification for Modbus RTU. My solution was to re-implement it from the ground up, (which took me less time than getting the NModbus source to compile and run in the first place, due to it's dependency on third part libraries for logging, etc & missing extensions for IEnumerable classes).

Using WinSocks in C to send data to a c# application on same machine, "target host refusing connectiong(c# part)

I am trying to get data from my interface, written in c, to another application, in c#.
Now, I'm not sure if WinSocks is pure c, but I'm using visual studio and the rest of my interface is 100% pure C.
Here is my "client" written in c#
http://pastebin.com/X9SNcVqn
here is my "server" written in c - loops waiting for a connection, this builds AND RUNS without issues
NOTE: DEFAULT_PORT is 18042, used the same port for client and server side.
I've downloaded wireshark and used the command "tcp.port eq "
http://pastebin.com/FHZyre2V
I also tried going through my windows firewall and NORTON to allow this connection, I couldn't figure out what to do. Most of the tuts I saw where outdated and tabs and options are changed in WINDOWS 7
I chose a port that wasn't being used, I tried using wireshark to see the connections, no luck BUT I scanned the port I used with nmap, before AND after I ran the "server", so it must of atleast have been created
In your C# code you are mixing TcpClient and Socket objects. You don't need both, only the TcpClient. (The Socket code is using the wrong port as well). Once the TcpClient object is connected, call the GetStream method to get a NetworkStream object that you can read and write to to send and receive data to the server process.
See the example code in the documentation, here: http://msdn.microsoft.com/en-us/library/system.net.sockets.tcpclient.aspx
Your client code contains:
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("192.168.1.4"), 18041);
I would not necessarily expect the IP address bound to a network card to necessarily work for localhost-to-localhost connections. I'd recommend changing your client to use 127.0.0.1 or another suitable loopback address.
First,check if the IP adress is correct and if the corresponding port is listeing.
netstat -an | find "port number"
and I think, in the server side code
local.sin_port = (unsigned short)DEFAULT_PORT;
Should be:
local.sin_port = htons((unsigned short)DEFAULT_PORT);

Asynch Socket Server and AS3 Flash Application - User Disconnects not handled

I have 2 sets of code for you to look at, both are available at PasteBin here:
First is my c# Socket server: http://pastebin.com/wvT4f19m
Second is my code within my AS3 application: http://pastebin.com/bKvabFSP
In the code, what I am trying to do is a simple Send/Receive to see what happens. If I open my application in 2 instances the c# socket server registers that they exist and all is fine!. If I close one of my instances, the c# server still thinks that the user exists and the socket isn't closed.
My code is based off the example at : http://msdn.microsoft.com/en-us/library/fx6588te.aspx
In the MS example, the following lines are added to the SendCallBack() function:
handler.Shutdown(SocketShutdown.Both);
handler.Close();
These definately close the sockets, something I do not want to happen.
I am new at socket programming and it has taken me a fair amount of time to play with the MS example to get it working roughly how I need it. The only problem is the acknowledgement of user disconnects so that I can remove the user from the Clients list that I have set up in the server. Also, when disconnects are acknowledged, I can inform other clients.
thanks all!
Upon each attempt to send data to the user, I do a quick check for a successful transmission/Poll the user and if it fails, the user is removed from my server.
Closing the socket won't affect your listener, it will only affect the current connection. Why do you say this is not what you want?
It sounds like this is exactly what you want.

Categories

Resources