I have a simple server-client socket apps which are used for send/receive files. I need to cover situation when connection is lost (I am using TCPView to crash it) using treads. So, using threads is a MUST situation and I am not sure how to do that. Here is my code for client and server side. Thanks.
Client:
public static void StartClient()
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
byte[] msg;
try
{
IPAddress ipAd = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteEP = new IPEndPoint(ipAd, 1234);
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
sender.Connect(remoteEP);
Console.WriteLine("Client connected to {0}", sender.RemoteEndPoint.ToString());
Console.WriteLine("Sending file...");
msg = File.ReadAllBytes(#"C:\TCPIP\test_big.txt");
byte[] msgLengthBytes = BitConverter.GetBytes(msg.Length-3);
int msgLength = BitConverter.ToInt32(msgLengthBytes, 0);
Console.WriteLine("int: {0}", msgLength);
Console.WriteLine("msgL size: {0}", msgLengthBytes.Length);
//join arrays
byte[] result = new byte[msgLengthBytes.Length + msgLength];
Buffer.BlockCopy(msgLengthBytes, 0, result, 0, msgLengthBytes.Length);
Buffer.BlockCopy(msg, 3, result, msgLengthBytes.Length, msgLength);
int bytesSent = sender.Send(result);
Console.WriteLine("result size: {0}", result.Length);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static void Main(String[] args)
{
StartClient();
}
Server:
public static void Main(String[] args)
{
StartListening();
}
public static void StartListening()
{
byte[] bytes = new Byte[1024];
while (true)
{
Console.WriteLine("Waiting for a connection...");
Socket handler = SocketInstance().Accept();
data = null;
//for the TCP header, get file information
bytes = new byte[4];
int bytesReceived = handler.Receive(bytes);
int Lenght = BitConverter.ToInt32(bytes, 0);
Console.WriteLine("msg length: " + Lenght);
int TotalReceivedBytes = 0;
while (TotalReceivedBytes < Lenght)
{
bytes = new byte[1024];
int bytesRec = handler.Receive(bytes);
TotalReceivedBytes = TotalReceivedBytes + bytesRec;
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
}
Console.WriteLine("Bytes received total: " + TotalReceivedBytes);
File.WriteAllText(outputPath, data);
Console.WriteLine(File.Exists(outputPath) ? "File received." : "File not received.");
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
private static Socket SocketInstance()
{
IPAddress ipAd = IPAddress.Parse("127.0.0.1");
IPEndPoint localEndPoint = new IPEndPoint(ipAd, 1234);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(localEndPoint);
listener.Listen(10);
return listener;
}
Related
I'm using c# sockets to create a client-server connection on my pc, for now locally, but the exception in the title is the only signal I receive back.
I've already tried disabling the firewall, checking if the port I'm using(51111) is listening(yes) and unticking everything in LAN settings(to avoid proxying), all of them at the same time too.
My code(just temporary test code)
Server Class
class Server
{
private Socket listener;
public void SocketServer()
{
int maxBuffer = 1024;
Console.WriteLine("LISTENER ENABLED");
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(new IPEndPoint(IPAddress.Any, 51111));
listener.Listen(5);
while (true)
{
Console.WriteLine("WAITING FOR CONNECTION");
Socket socket = listener.Accept();
string receivedMessage = string.Empty;
while (true)
{
byte[] receivedBytes = new byte[maxBuffer];
int bytesReceivedCount = socket.Receive(receivedBytes);
receivedMessage += Encoding.ASCII.GetString(receivedBytes, 0, bytesReceivedCount);
if (receivedMessage.IndexOf('\n') > -1)
{
break;
}
}
Console.WriteLine("Message from Client : " + receivedMessage);
string reply = ("Message received!");
byte[] replyBytes = Encoding.ASCII.GetBytes(reply);
socket.Send(replyBytes);
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
Client Class
class Client
{
public void SocketClient(string request)
{
int maxBuffer = 1024;
try
{
IPHostEntry iPHostEntry = Dns.GetHostEntry(Dns.GetHostName());
IPAddress address = iPHostEntry.AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(address, 51111);
Socket sender = new Socket(address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
sender.Connect(remoteEP);
Console.WriteLine("Connected to " + sender.RemoteEndPoint.ToString());
byte[] message = Encoding.ASCII.GetBytes(request);
int bytesSent = sender.Send(message);
byte[] response = new byte[maxBuffer];
int bytesReceived = sender.Receive(response);
Console.WriteLine("Received : " + Encoding.ASCII.GetString(response, 0, bytesReceived));
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
Thank you
I'm trying to build an Asynchronous Chat Server and this is what I got so far:
Server
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousSocketListener
{
public static ManualResetEvent allDone = new ManualResetEvent(false);
public AsynchronousSocketListener()
{
}
public static void StartListening()
{
byte[] bytes = new Byte[1024];
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
Socket listener = new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);
try
{
listener.Bind(localEndPoint);
listener.Listen(100);
while (true)
{
allDone.Reset();
Console.WriteLine("Waiting for a connection...");
listener.BeginAccept(new AsyncCallback(AcceptCallback),listener);
allDone.WaitOne();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
Console.WriteLine("\nPress ENTER to continue...");
Console.Read();
}
public static void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);
}
public static void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1)
{
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",content.Length, content);
Send(handler, content);
}
else
{
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReadCallback), state);
}
}
}
private static void Send(Socket handler, String data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
handler.BeginSend(byteData, 0, byteData.Length, 0,new AsyncCallback(SendCallback), handler);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket handler = (Socket)ar.AsyncState;
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args)
{
StartListening();
return 0;
}
}
Client
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 256;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
public class AsynchronousClient
{
private const int port = 11000;
private static ManualResetEvent connectDone =new ManualResetEvent(false);
private static ManualResetEvent sendDone =new ManualResetEvent(false);
private static ManualResetEvent receiveDone =new ManualResetEvent(false);
private static String response = String.Empty;
static String username = "";
static int a = 1;
private static void StartClient()
{
try
{
Console.WriteLine("Username: ");
username = Console.ReadLine();
while (a == 1)
{
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
Console.WriteLine("Receiver: ");
String receiver = Console.ReadLine();
Console.WriteLine("Message: ");
String message = Console.ReadLine();
String Message = username + "[" + receiver + "[" + message + "<EOF>";
Send(client, Message);
sendDone.WaitOne();
Receive(client);
receiveDone.WaitOne();
Console.WriteLine("Response received : {0}", response);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndConnect(ar);
connectDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
StateObject state = new StateObject();
state.workSocket = client;
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,new AsyncCallback(ReceiveCallback), state);
}
else
{
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, String data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, 0,new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args)
{
StartClient();
return 0;
}
}
I'm able to send messages to the server and get back an answer, but the connection is cut every time and I have to reconnect it and like this I wouldn't be able to get messages after I send one. I'm looking for a way to connect my client to the server, send messages in both ways and stop the connection manualy.
Furthermore I'm looking for a way to send messages from one client to another one and to send a message to all clients, who are connected to the server.
Another Question I have, how can I set up multiple ports and let the server listen to all ports? I wanted to open one port for the login and one port for the messages.
I'm looking for a way to connect my client to the server, send messages in both ways and stop the connection manualy.
Closing the connection could be done by adding a disconnect call after the loop: client.Disconnect(false). After some exit condition you simply quit the loop.
It would be preferable to create the client in a using statement though, this way it will be disposed automatically.
but the connection is cut every time
because your explicitly close it in SendCallback
Socket handler = (Socket) ar.AsyncState;
handler.Shutdown(SocketShutdown.Both);
handler.Close();
You may call handler.BeginReceive instead
public static byte[] StartClient(string ip, int port, byte[] message, bool needBack, out string errorMsg)
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
IPAddress ipAddress = IPAddress.Parse(ip);
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
sender.Connect(remoteEP);
// Send the data through the socket.
int bytesSent = sender.Send(message);
if (needBack)
{
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
byte[] array = new byte[bytesRec];
Array.Copy(bytes, array, bytesRec);
sender.Shutdown(SocketShutdown.Both);
sender.Close();
errorMsg = "";
return array;
}
else
{
errorMsg = "";
return null;
}
}
catch (ArgumentNullException ane)
{
errorMsg = string.Format("ArgumentNullException : {0}", ane.ToString());
return null;
}
catch (SocketException se)
{
errorMsg = string.Format("SocketException : {0}", se.ToString());
return null;
}
catch (Exception e)
{
errorMsg = string.Format("Unexpected exception : {0}", e.ToString());
return null;
}
}
catch (Exception e)
{
errorMsg = string.Format("Unexpected exception : {0}", e.ToString());
return null;
}
}
I use the code above to send and receive tcp message from the server.but I read nothing.
I don't want a async method.I have searched some example codes, they are written like this. Is there something wrong that I didn't realized.Thanks for help.
public class MyTcpClient
{
IPEndPoint _remote;
Socket _socket;
public bool IsStopReceive{set;get;}
public MyTcpClient(string ip, int port)
{
IPAddress ipAddress = IPAddress.Parse(ip);
_remote = new IPEndPoint(ipAddress, port);
_socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
_socket.Connect(_remote);
ThreadPool.QueueUserWorkItem(obj=>{
IsStopReceive = false;
ReceiveMsg();
});
}
public void Send(byte[] bytes) {
_socket.Send(bytes);
}
private MemoryStream memoryResult;
private void ReceiveMsg()
{
MemoryStream memStream = new MemoryStream();
while (!IsStopReceive)
{
byte[] bytes=new byte[1024];
int result = _socket.Receive(bytes);
if (result > 0) {
memStream.Write(bytes, 0, result);
}
else if (result == 0) {
IsStopReceive = true;
break;
}
}
if (OnMsgReceive != null) {
OnMsgReceive(memStream.GetBuffer());
}
}
public Action<byte[]> OnMsgReceive{set;get;}
}
the code above can receive the data.when I create a MyTcpClient instance,it will open a thread to receive data after connect to the target.
I use a Action to get the data after it finished.but this is async.Most important is that I don't know why I missed the data with the prev method.
I used to write socket programs in C and can't understand why the above is happening.
My server blocks at a Receive call, when it returns 0, I break out of the while loop and shutdown the thread.
public class MyServer {
public MyServer() {
}
public void Init() {
ThreadPool.QueueUserWorkItem(StartListening);
while (true) {
Console.Read();
}
}
public void StartListening(Object state) {
// Establish the local endpoint for the socket.
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try {
// Bind the socket to the local endpoint and listen for incoming connections.
listener.Bind(localEndPoint);
listener.Listen(100);
while (true) {
Console.WriteLine("Waiting for a connection...");
// get connection
Socket client = listener.Accept();
// push client to another thread
ThreadPool.QueueUserWorkItem(HandleClient, client);
}
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
private void HandleClient(Object obj) {
// Get the socket that handles the client request.
Socket client = (Socket)obj;
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
try {
while (true) {
int bytesRead = client.Receive(state.buffer);
Console.WriteLine("bytesRead=" + bytesRead);
// remote dc.
if (bytesRead == 0)
break;
String content = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
client.Send(state.buffer, 0, state.buffer.Length, 0);
}
} catch (SocketException e) {
Console.WriteLine("SocketException : {0}", e.ToString());
}
client.Shutdown(SocketShutdown.Both);
client.Close();
}
private void Send(Socket handler, String data) {
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
//handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}
}
However, when I click on the close button ("x") of the client, server's Receive call throws a SocketException. According to MSDN's Remarks section, this shouldn't happen because I've satisfied both the connection-oriented part (see above) and client shutdown part(see below) conditions.
Client.cs (pseudo):
public class MyClient {
public void Init() {
byte[] bytes = new byte[1024];
Socket sender = null;
try {
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint remoteEP = new IPEndPoint(ipAddress, 11000);
sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}",
sender.RemoteEndPoint.ToString());
while (true) {
// Encode the data string into a byte array.
String input = Console.ReadLine();
byte[] msg = Encoding.ASCII.GetBytes(input);
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}",
Encoding.ASCII.GetString(bytes, 0, bytesRec));
}
} catch (ArgumentNullException ane) {
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
} catch (SocketException se) {
Console.WriteLine("SocketException : {0}", se.ToString());
} catch (Exception e) {
Console.WriteLine("Unexpected exception : {0}", e.ToString());
} finally {
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
}
}
My shallow understanding of finally blocks is that it will always execute. But it doesn't seem to be the case here.
SO, what did I do wrong here? Should I just catch the exception, close the client socket on the server side and just move on, ignoring it? But I would prefer if an exception were not thrown at all.
this is my code for Monitoring Http:
static void Main(string[] args)
{
try
{
byte[] input = BitConverter.GetBytes(1);
byte[] buffer = new byte[4096];
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
s.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 80));
s.IOControl(IOControlCode.ReceiveAll, input, null);
s.BeginReceive(arrResponseBytes, 0, arrResponseBytes.Length, SocketFlags.None, new AsyncCallback(OnClientReceive), s);
System.Threading.ManualResetEvent reset = new System.Threading.ManualResetEvent(false);
reset.WaitOne();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadKey();
}
static byte[] arrResponseBytes = new byte[1024 * 5];
protected static void OnClientReceive(IAsyncResult ar)
{
Socket socket = (Socket)ar.AsyncState;
int count = socket.EndReceive(ar);
if (count > 0)
{
Console.WriteLine(Encoding.ASCII.GetString(arrResponseBytes, 0, count));
socket.BeginReceive(arrResponseBytes, 0, arrResponseBytes.Length, SocketFlags.None, new AsyncCallback(OnClientReceive), socket);
}
}
but i cannot get http hosts.
I do not know what data.
i want to get http host for example:
http://google.com
how can i monitor system http?
thanks.
What you see in your link is the IP + TCP headers. You should parse the IP&TCP headers to extract the content. TCP content starts approximately at offset 40. So you can try your program's modified version as below to see the content of each HTTP request. (Working but not complete program just to give you an idea)
PS: See the s.Bind(new IPEndPoint(IPAddress.Broadcast, 80));
static void Main(string[] args)
{
try
{
byte[] input = new byte[]{1};
byte[] buffer = new byte[4096];
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
s.Bind(new IPEndPoint(IPAddress.Broadcast, 80));
s.IOControl(IOControlCode.ReceiveAll , input, null);
s.BeginReceive(arrResponseBytes, 0, arrResponseBytes.Length, SocketFlags.None, new AsyncCallback(OnClientReceive), s);
System.Threading.ManualResetEvent reset = new System.Threading.ManualResetEvent(false);
reset.WaitOne();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadKey();
}
static byte[] arrResponseBytes = new byte[1024 * 64];
static void OnClientReceive(IAsyncResult ar)
{
Socket socket = (Socket)ar.AsyncState;
int count = socket.EndReceive(ar);
if (count >= 40)
{
try
{
string s = Encoding.UTF8.GetString(arrResponseBytes, 40, count - 40);
string bin = BitConverter.ToString(arrResponseBytes, 40, count - 40).Replace("-", " ");
if(s.StartsWith("GET"))
Console.WriteLine(s + " - " + bin);
//Thread.Sleep(1000);
}
catch { }
}
socket.BeginReceive(arrResponseBytes, 0, arrResponseBytes.Length, SocketFlags.None, new AsyncCallback(OnClientReceive), socket);
}