I want to do the following with a raw C# socket. I understand that usually the most appropriate way is via HTTP, with a HTTP client. The browser understands that this connection must be kept open in some way.
http://server.domain.com/protocol/do_something.txt
I am trying the following in C#, but have had no luck. What am I doing wrong? Is there a header missing? Should I be encoding what I'm sending to the server in some way? For the ReceiverSocket client, I'm using the following code, but it's just a very standard asynchronous socket client: https://stackoverflow.com/a/10390066/971580
ReceiverSocket socket = new ReceiverSocket("server.domain.com", 80);
socket.Connect();
System.Threading.Thread.Sleep(1000);
String message = "GET /protocol/do_something.txt HTTP/1.1";
message += "\r\n";
message += "\r\n";
socket.Send(message);
The socket can connect successfully, but I don't get any response when I send anything to the server. This is how I am connecting, sending and receiving.t (Apologies: I tried to do this in snippets, rather than including all the methods, but it looked horrid. . .)
public ReceiverSocket(String address, int port) : base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
messageQueue = new Queue<MessageBase>();
IPHostEntry ipHostInfo = Dns.GetHostEntry(address);
IPAddress ipAddress = ipHostInfo.AddressList[0];
remoteEP = new IPEndPoint(ipAddress, port);
}
public void Connect()
{
this.BeginConnect(remoteEP, ConnectCallback, this);
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
if (client.Connected)
{
client.EndConnect(ar);
Console.WriteLine("Connect Callback - Connected");
StateObject state = new StateObject();
state.workSocket = client;
state.BufferSize = 8192;
if (SocketConnected != null)
SocketConnected(client);
client.BeginReceive(state.Buffer, state.readOffset, state.BufferSize - state.readOffset, 0, ReceiveCallback, state);
}
else
{
Thread.Sleep(5000);
Connect();
}
}
catch (Exception ex)
{
Reconnect();
}
}
private void ReceiveCallback(IAsyncResult ar)
{
Console.WriteLine("Never gets here. . . ");
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
if (client.Connected)
{
int bytesRead = client.EndReceive(ar);
foreach (MessageBase msg in MessageBase.Receive(client, bytesRead, state))
{
// Add objects to the message queue
lock (this.messageQueue)
this.messageQueue.Enqueue(msg);
}
if (DataRecieved != null)
DataRecieved(client, null);
client.BeginReceive(state.Buffer, state.readOffset, state.BufferSize - state.readOffset, 0, ReceiveCallback, state);
}
else
{
Reconnect();
}
}
catch (SocketException)
{
Reconnect();
}
}
public void Send(String msg)
{
try
{
byte[] bytes = GetBytes(msg);
if (this.Connected)
{
Console.WriteLine("Sending: " + msg);
this.BeginSend(bytes, 0, bytes.Length, 0, SendCallback, this);
}
else
{
Reconnect();
}
}
catch (SocketException sox)
{
Reconnect();
}
catch (Exception ex)
{
int i = 0;
}
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
}
public class StateObject
{
public Socket workSocket = null;
public int readOffset = 0;
public StringBuilder sb = new StringBuilder();
private int bufferSize = 0;
public int BufferSize
{
set
{
this.bufferSize = value;
buffer = new byte[this.bufferSize];
}
get { return this.bufferSize; }
}
private byte[] buffer = null;
public byte[] Buffer
{
get { return this.buffer; }
}
}
Shouldn't the fact that I haven't included the message += "Connection: close"
header mean that the socket should just start sending whatever data it has asynchronously? Just to note also: I can connect successfuly using Telnet and send the data, just not with a socket yet!
Any pointers at all would be appreciated.
Thanks.