I have this code:
public static List<Socket> samp = new List<Socket>();
Socket connection/etc in form load..
IPHostEntry host = null;
Socket sock;
host = Dns.GetHostEntry(sending ip..);
foreach (IPAddress address in host.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, 7777);
sock = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(ipe);
if (sock.Connected)
{
sock.SendTo(Encoding.UTF8.GetBytes("App starts"), ipe);
samp.Add(sock);
}
}
In form closing:
if (samp.Count > 0)
{
foreach (Socket socket in samp)
{
socket.Send(Encoding.UTF8.GetBytes("App closing"));
socket.Close();
}
}
And i'm getting error:
Cannot access a disposed object. Object name: 'System.Net.Sockets.Socket'
Thanks in advance!
P.S looks like socket.Close() works, but socket.Send nope :(
Related
I'm trying to save a connected socket in a dictionary so my API doesn't have to create a new connection every time. My problem is that the socket gets disposed.
So when I call GetConnection() a second time socket.connected is false and socket.Available.Message is "Cannot access a disposed object. Object name: 'System.Net.Sockets.Socket'.".
public static class ModbusSocket
{
private static Dictionary<IPAddress, Socket> socketList;
public static Socket GetConnection(string server, int port)
{
if (socketList is null)
{
socketList = new Dictionary<IPAddress, Socket>();
}
IPAddress iPAddress = IPAddress.Parse(server);
if (socketList.ContainsKey(iPAddress))
{
var socket = socketList[iPAddress];
if (socket.Connected)
{
return socket;
}
else
{
socketList.Remove(iPAddress);
socket = new Socket(iPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipe = new IPEndPoint(iPAddress, port);
socket.Connect(ipe);
socketList.Add(iPAddress, socket);
return socket;
}
}
else
{
Socket socket = new Socket(iPAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipe = new IPEndPoint(iPAddress, port);
socket.Connect(ipe);
socketList.Add(iPAddress, socket);
return socket;
}
}
}
OMG I found the issue...
I invoked it with using:
using (Socket s = ModbusSocket.GetConnection(hostIp, port))
{
var telegram = new Telegram();
telegram.Set(0, AddressConst.PositionWindow, 4);
var response = telegram.SendAndReceive(s);
var result = BitConverter.ToInt32(new byte[] { response.Byte19, response.Byte20, response.Byte21, response.Byte22 }, 0);
return result;
}
I have this code:
public static List<Socket> samp = new List<Socket>();
IPHostEntry host = null;
Socket sock;
host = Dns.GetHostEntry(sending ip..);
foreach (IPAddress address in host.AddressList)
{
IPEndPoint ipe = new IPEndPoint(address, 7777);
sock = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(ipe);
if (sock.Connected)
{
samp.Add(sock);
}
}
This code work's okay. It send's my ip. How it looks in console:
How can I send custom string? For example i'm tried this code:
if (sock.Connected)
{
byte[] msg = Encoding.UTF8.GetBytes("This is a test");
byte[] bytes = new byte[256];
int i = sock.Send(msg);
MessageBox.Show(string.Format("Sent {0} bytes.", i));
samp.Add(sock);
}
It shows message: Sent 14 bytes. But in the console nothing prints.. How can I send this text to console? I'm also tried this:
sock.Send(Encoding.UTF8.GetBytes("This is a test"));
And this not prints :(
Thanks in advance !
I went to request to open socket from web service to be like notification when the database change . The client is request to web service when it's connection to internet to apply to web service to get his IP Address then web service can send in this IP socket when database change . And client have socket open response the request .
Code of web service in Remote host
[WebMethod]
public string GetMyIpAddress()
{
string adree = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; //get client request ip address
byte[] bytes = new byte[1024];
try
{
IPAddress ipaddress = IPAddress.Parse(adree);
IPEndPoint remote = new IPEndPoint(ipaddress, 1093);
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sender.Connect(remote);
byte[] meg = Encoding.ASCII.GetBytes("This is a test<EOF>"); // send message to client in it's ip address
int bytesend = sender.Send(meg);
int byterecive = sender.Receive(bytes);
string red = Encoding.ASCII.GetString(bytes, 0, byterecive);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
return(red);
}
catch (Exception e)
{
return(e.ToString());
}
}
Code of client socket
class Program
{
public static string data = null;
static void Main(string[] args)
{
byte[] bytes = new byte[1024];
IPHostEntry iphostinfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipaddress = iphostinfo.AddressList[0];
IPEndPoint localendpoint = new IPEndPoint(ipaddress, 1093);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localendpoint);
listener.Listen(10);
while (true)
{
Console.WriteLine("Waiting for a connection...");
Socket hander = listener.Accept();
data = null;
while (true)
{
bytes = new byte[1024];
int bytsize = hander.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytsize);
if (data.IndexOf("<EOF>") > -1)
{
break;
}
}
Console.WriteLine("Text received : {0}", data);
byte[] meg = Encoding.ASCII.GetBytes(data);
hander.Send(meg);
hander.Shutdown(SocketShutdown.Both);
hander.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
}
The problem when i request to web service to get my client IP address and send to this IP address for test i get this problem :
System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respond after a period of time, or est ablished connection failed because connected host has failed to respond 41.218.1
9.226:1093
Please help me how can solve this problem ?
If I have a callback from a
listener.BeginAcceptSocket(cbConnect, listener);
and my callback method:
private void cbConnect(IAsyncResult ar)
{
TcpListener listener = (TcpListener)ar.AsyncState;
MyObj myObj = new MyObj();
myObj.socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
myObj.socket = listener.EndAcceptSocket(ar);
listener.BeginAcceptSocket(cbConnect, listener);//start listening again
myObj.socket.BeginReceive(myObj.buffer, 0, myObj.buffer.Length, 0, cbReceive, myObj);
}
Here is MyObj class:
Public class MyObj
{
public Socket socket;
public byte[] buffer = new byte[1080];
}
My question is if the client on the other end of the connection never sends any data what will happen to myObj?
How would I close the socket and mop up resources?
If the remote connection drops, the socket should cleanup on it's own via the Garbage Collector.
The function Dns.GetHostEntry doesn't handle ipaddresses as strings e.g. 127.0.0.1 but if I pass google.de as a parameter it works quite well.
Am I doing something wrong ?
public static Socket connSock(string Server, int Port)
{
Socket s = null;
IPHostEntry ipHE = Dns.GetHostEntry(Server);
//IPAddress[] ipA = null;
IPEndPoint ipE = null;
foreach (IPAddress address in ipHE.AddressList)
{
ipE = new IPEndPoint(address, Port);
Socket tempSocket = new Socket(ipE.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
tempSocket.Connect(ipE);
if (tempSocket.Connected)
{
s = tempSocket;
break;
}
else
{
continue;
}
}
return s;
}
This could mean you're system is unable to get the host entry. This occurs (for instance) when there's no PTR record defined for the given IP.