I am trying to receive data from an app connected to my server but it is sending the data as null?
//Receive Data
int received = socket.EndReceive(AR);
byte[] dataBuf = new byte[received];
Array.Copy(_buffer, dataBuf, received);
string ReserveText = Encoding.ASCII.GetString(dataBuf);
//Write to Console if no error appears
Console.WriteLine("Message received from client: " + ReserveText);
It is currently printing Message received from client: and it is ment to print the 'ReserveText' after it but the reserve test is obviously empty? The above code is my server code and below I have shared the full void and the code in the client.
Full Void:
public void ReceiveCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
string clientIP = socket.RemoteEndPoint.ToString();
try
{
//Receive Data
int received = socket.EndReceive(AR);
byte[] dataBuf = new byte[received];
Array.Copy(_buffer, dataBuf, received);
string ReserveText = Encoding.ASCII.GetString(dataBuf);
//Write to Console if no error appears
Console.WriteLine("Message received from client: " + ReserveText);
string ResponceText = "Testing Response";
byte[] data = Encoding.ASCII.GetBytes(ResponceText);
//socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
SendAsync(socket, data, 0, data.Length);
Console.WriteLine("Message sent to client: " + ResponceText);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback),
socket);
}
catch (Exception)
{
Console.WriteLine("Client Disconnected");
//TODO: DISPOSE THE SOCKET/SESSION FROM _clients
}
}
Here is the method on the client side SENDING to the server
public static string SendMessageAndReturnResponse(string req)
{
byte[] buffer = Encoding.ASCII.GetBytes(req);
_clientSocket.Send(buffer);
byte[] receivedBuf = new byte[1024];
int rec = _clientSocket.Receive(receivedBuf);
byte[] data = new byte[rec];
Array.Copy(receivedBuf, data, rec);
return Encoding.ASCII.GetString(data);
}
Related
I have a problem with sending or receiving image (I don't know which part fails because my image is getting cutted on receive). I know that this kind of problem has much posts about it but any of these wasn't working for me.
So simply I have "my" socket server (not TCPClient). Server have to get screenshot of screen and send it to the client.
private static void ReceiveCallback(IAsyncResult AR)
{
Socket current = (Socket)AR.AsyncState;
int received;
IPEndPoint remoteIpEndPoint = current.RemoteEndPoint as IPEndPoint;
try
{
received = current.EndReceive(AR);
}
catch (SocketException)
{
current.Close();
return;
}
byte[] recBuf = new byte[received];
Array.Copy(buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Write("Received Text: ");
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine(text);
if(text.ToLower() == "screenshot")
{
Image a = get_image.doscreen();
current.Send(ImageToByte(a));
}
if(current.Connected)
current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
}
I know that's not much code to show but I've done this server from tutorial and whole code it's pretty basic. Also I know that it might be buffer problem but I don't know how to fix this.
"My" client code:
private static void send()
{
try
{
string req = Console.ReadLine();
byte[] buffer = Encoding.ASCII.GetBytes(req);
_clientsocket.Send(buffer);
byte[] receivedbuf = new byte[1024];
int rec = _clientsocket.Receive(receivedbuf, receivedbuf.Length, SocketFlags.None);
byte[] data = new byte[rec];
Array.Copy(receivedbuf, data, rec);
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine(Encoding.ASCII.GetString(data));
if (req.ToLower() == "screenshot")
{
File.WriteAllBytes("test.png", data);
}
}
catch(Exception){
}
}
All i want to do is send message to client from server. I try a lot of tutorial etc. but still can't send message from server to client.
Send from client to server is simple and have it in code. When client Send "HI" to server i want to respond Hi to client. But dunno what should i add to my code. Can someone help me with that? Please don't do it like duplicate i know there is a lot of similar topic but can't find solution.
Server code:
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
IPAddress ip = Dns.GetHostEntry("localhost").AddressList[0];
TcpListener server = new TcpListener(ip, Convert.ToInt32(8555));
TcpClient client = default(TcpClient);
try
{
server.Start();
Console.WriteLine("Server started...");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
};
while (true)
{
client = server.AcceptTcpClient();
byte[] receivetBuffer = new byte[100];
NetworkStream stream = client.GetStream();
stream.Read(receivetBuffer, 0, receivetBuffer.Length);
StringBuilder msg = new StringBuilder();
foreach(byte b in receivetBuffer)
{
if (b.Equals(59))
{
break;
}
else
{
msg.Append(Convert.ToChar(b).ToString());
}
}
////Resive message :
if (msg.ToString() =="HI")
{
///#EDIT 1
///// HERE Is SENDING MESSAGE TO CLIENT//////////
int byteCount = Encoding.ASCII.GetByteCount("You said HI" + 1);
byte[] sendData = new byte[byteCount];
sendData = Encoding.ASCII.GetBytes("You said HI" + ";");
stream.Write(sendData, 0, sendData.Length);
}
}
Client code:
private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
try
{
string serverIP = "localhost";
int port = Convert.ToInt32(8555);
TcpClient client = new TcpClient(serverIP, port);
int byteCount = Encoding.ASCII.GetByteCount("HI"+ 1);
byte[] sendData = new byte[byteCount];
sendData = Encoding.ASCII.GetBytes("HI" + ";");
NetworkStream stream = client.GetStream();
stream.Write(sendData, 0, sendData.Length);
///////////////////////////////HERE I WANT A read message from server/
/////////////////////////////////////////////////////////////////////
stream.Close();
client.Close();
}
catch(Exception ex)
{
ex.ToString();
}
}
Try this Here is my version of client and server ,feel free to ask if any reference problem ,the client wait for server to (online) then if server is online connect with it.
Method to Connect with Server
private void Connectwithserver(ref TcpClient client)
{
try
{
//this is server ip and server listen port
server = new TcpClient("192.168.100.7", 8080);
}
catch (SocketException ex)
{
//exceptionsobj.WriteException(ex);
Thread.Sleep(TimeSpan.FromSeconds(10));
RunBoTClient();
}
}
byte[] data = new byte[1024];
string stringData;
TcpClient client;
private void RunClient()
{
NetworkStream ns;
Connectwithserver(ref client);
while (true)
{
ns = client.GetStream();
//old
// ns.ReadTimeout = 50000;
//old
ns.ReadTimeout = 50000;
ns.WriteTimeout = 50000;
int recv = default(int);
try
{
recv = ns.Read(data, 0, data.Length);
}
catch (Exception ex)
{
//exceptionsobj.WriteException(ex);
Thread.Sleep(TimeSpan.FromSeconds(10));
//try to reconnect if server not respond
RunClient();
}
//READ SERVER RESPONSE/MESSAGE
stringData = Encoding.ASCII.GetString(data, 0, recv);
}
}
Server
IPAddress localAdd = IPAddress.Parse(SERVER_IP);
TcpListener listener = new TcpListener(localAdd, PORT_NO);
Console.WriteLine("Listening...");
listener.Start();
while (true)
{
//---incoming client connected---
TcpClient client = listener.AcceptTcpClient();
//---get the incoming data through a network stream---
NetworkStream nwStream = client.GetStream();
byte[] buffer = new byte[client.ReceiveBufferSize];
//---read incoming stream---
int bytesRead = nwStream.Read(buffer, 0, client.ReceiveBufferSize);
//---convert the data received into a string---
string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead);
Console.WriteLine("Received : " + dataReceived);
//IF YOU WANT TO WRITE BACK TO CLIENT USE
string yourmessage = console.ReadLine();
Byte[] sendBytes = Encoding.ASCII.GetBytes(yourmessage);
//---write back the text to the client---
Console.WriteLine("Sending back : " + yourmessage );
nwStream.Write(sendBytes, 0, sendBytes.Length);
client.Close();
}
listener.Stop();
How can I stop sending message to a client, while client do not read a message from server. To better understand what this means, consider a scenario in which a client does not call Read for an extended period of time, and server stops sending message to this client.
Server.cs receive message from client, and send to all clients
private static void ReceiveCallback(IAsyncResult AR)
{
Socket current = (Socket)AR.AsyncState;
int received;
try
{
received = current.EndReceive(AR);
}
catch (SocketException)
{
Console.WriteLine("Client forcefully disconnected");
current.Close();
clientSockets.Remove(current);
return;
}
byte[] recBuf = new byte[received];
Array.Copy(buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
Console.WriteLine("Received Text: " + text);
buffQueue.Enqueue(text);
current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
foreach (var client in clientSockets)
{
foreach (var msg in buffQueue)
{
Sendata(client, text);
}
}
}
static void Sendata(Socket socket, string noidung)
{
byte[] data = Encoding.ASCII.GetBytes(noidung);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
}
private static void SendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
}
Client.cs
public void ReceiveMessage(IAsyncResult ar)
{
Random rnd = new Random();
Socket socket = (Socket)ar.AsyncState;
int received = socket.EndReceive(ar);
byte[] dataBuf = new byte[received];
Array.Copy(receivedBuf, dataBuf, received);
string msg = Encoding.ASCII.GetString(dataBuf);
Console.WriteLine("> " + msg + '\n');
ClientSocket.BeginReceive(receivedBuf, 0, receivedBuf.Length, SocketFlags.None,
new AsyncCallback(ReceiveMessage), ClientSocket);
}
The problem is, that when a client does not read the buffer, the receivebuffer of the client will be full and the server will block in execution. You could prevent this by either:
Queue the data for each client. The client must request data, so the server will send it's queue. (on a different thread)
Use the socket.Blocking = false on the socket on the server. When the server is sending the data and the buffers are full, you'll get an WouldBlock exception or when using the right overload on sending, a SocketErrorCode is returned. Windows Sockets: Blocking. You still need a queue.
The SendData could be done parallel, because the bytebuffer/data doesn't change while sending.
First of all, what my Project should do if it would work:
Client written in C++ connects to Server coded in C#
When Connection was successfully, Client sends "0" to the Server to request a random String of Hexadecimals
If the Client recieved the Hexadecimals he will send "1" to the Server
Now the Client does some Stuff with the recieved Hexadecimalstring and then sends it back to the Server
if what the client did to the Hexadecimalstring was correct(Basic authing System) he returns "1" otherwise he returns "0"
Note: The recieving/sending on Client/Server side works, i tested it before by just sending 1 to the Server and the Server returns 0 if the recieved String was 1
Now to my Coding:
Thats the Server Part written in C#:
private static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
private static List<Socket> clientSockets = new List<Socket>();
private const int PORT = 11111;
private static byte[] buffer = new byte[100];
private void ReceiveCallback(IAsyncResult AR)
{
Socket current = (Socket)AR.AsyncState;
int received;
try
{
received = current.EndReceive(AR);
}
catch (SocketException)
{
Console.WriteLine("Client Disconnected! (Forced)");
current.Close();
clientSockets.Remove(current);
return;
}
//That's how my Example before worked:
/*byte[] recBuf = new byte[1];
Array.Copy(buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
if(text != "" && text.StartsWith("0"))
{
Console.WriteLine("Recieved: " + text);
string send = "1";
Console.WriteLine("Sending: " + send);
Byte[] data = ASCIIEncoding.ASCII.GetBytes(send);
current.Send(data);
Console.WriteLine("Sended!");
current.Shutdown(SocketShutdown.Both);
current.Close();
clientSockets.Remove(current);
Console.WriteLine("Client Disconnected!");
return;
}
current.BeginReceive(buffer, 0, 1, SocketFlags.None, ReceiveCallback, current);*/
//worked like a charm!
//That's my new Solution, that doesn't work:
byte[] recBuf = new byte[100];
Array.Copy(buffer, recBuf, received);
string text = Encoding.ASCII.GetString(recBuf);
while (text != "")
{
Console.WriteLine("Received Data: " + text);
if (text.StartsWith("0") && text.Length < 32)
{
Console.WriteLine("Client requests Random HexString...");
string rand = GetRandomHexNumber(32);
Byte[] data = ASCIIEncoding.ASCII.GetBytes(rand);
current.Send(data);
Console.WriteLine("Sended HexString! - " + rand);
}
if (text.StartsWith("1") && text.Length < 32)
{
Console.WriteLine("Client recieved the HexString!");
}
if (text.Length > 32 && !text.StartsWith("0") && !text.StartsWith("1"))
{
Console.WriteLine("Result recieved!");
//here will be some authing process but for simplicity just return "1"
byte[] data = ASCIIEncoding.ASCII.GetBytes("1");
current.Send(data);
current.Shutdown(SocketShutdown.Both);
current.Close();
clientSockets.Remove(current);
Console.WriteLine("Client Disconnected!");
return;
}
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
}
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
}
private void AcceptCallback(IAsyncResult AR)
{
Socket socket;
try
{
socket = serverSocket.EndAccept(AR);
}
catch (ObjectDisposedException)
{
return;
}
clientSockets.Add(socket);
socket.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, socket);
Console.WriteLine("Client Connected!");
serverSocket.BeginAccept(AcceptCallback, null);
}
private void setupServer()
{
serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT));
serverSocket.Listen(0);
Console.WriteLine("Server Started!");
Console.WriteLine("Listening for Clients...");
serverSocket.BeginAccept(AcceptCallback, null);
}
private void CloseAllSockets()
{
foreach (Socket socket in clientSockets)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
serverSocket.Close();
}
setupServer(); gets launched on Console startup!
The C# part is the only problematic on the c++ side everything is fine!
I really hope somebody is able to help me now, since i didn't recieved any kind of help yet on this forum and i'm really in need for this to work and i'm sure here are plenty of programmers that could help me(maybe it's just a logical issue so every answer or comment is appreciated)
Thanks for your time :)
Replace
while (text != "")
{
// .....................
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
}
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
with
if (text != "")
{
// .....................
// Notice there's no BeginReceive() here!
}
if (current.Connected)
current.BeginReceive(buffer, 0, 100, SocketFlags.None, ReceiveCallback, current);
The function passed as callback paramater to BeginReceive() normally should not call BeginReceive() in a loop "until session is over". Instead it should call the BeginReceive() only once to pend another read operation if further data is expected (i.e. "session in not over").
OK, so I am not very good at programming in general, but I want to try my hand at using sockets. To start I watched a Youtube video which I followed step by step, I got the finished product working 100% to the guides however I wish to modify it in order for the server to be able to send a message to all connected clients.
Here is the youtube video: Youtube Video - Sockets
So this is the code for the server class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
namespace Server
{
class Program
{
private static byte[] buffer = new byte[1024];
public static Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public static List<Socket> clientSockets = new List<Socket>();
static void Main(string[] args)
{
Console.Title = "Server, " + clientSockets.Count.ToString() + " clients are connected";
SetupServer();
Console.ReadLine();
}
public static void SetupServer()
{
Console.WriteLine("Setting up server...");
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
_serverSocket.Listen(5);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
public static void AcceptCallback(IAsyncResult AR)
{
Socket socket = _serverSocket.EndAccept(AR);
clientSockets.Add(socket);
Console.WriteLine("Client Connected");
Console.Title = "Server, " + clientSockets.Count.ToString() + " clients are connected";
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
private static void RecieveCallBack(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
byte[] databuff = new byte[received];
Array.Copy(buffer, databuff, received);
string s = Encoding.ASCII.GetString(databuff);
Console.WriteLine("Text Received: " + s);
string response = string.Empty;
if (s.ToLower() == "get time")
{
response = DateTime.Now.ToLongTimeString();
}
else
{
response = "Invalid Request";
}
byte[] data = Encoding.ASCII.GetBytes(response);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(sendCallback), socket);
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), socket);
}
private static void sendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
}
}
}
I had a pretty pathetic attempt at what I wanted to do:
private static void RecieveCallBack(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
int received = socket.EndReceive(AR);
byte[] databuff = new byte[received];
Array.Copy(buffer, databuff, received);
string s = Encoding.ASCII.GetString(databuff);
Console.WriteLine("Text Received: " + s);
foreach(Socket s1 in clientSockets){
string response = string.Empty;
if (s.ToLower() == "get time")
{
response = DateTime.Now.ToLongTimeString();
}
else
{
response = "Invalid Request";
}
byte[] data = Encoding.ASCII.GetBytes(response);
s1.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(sendCallback), s1);
s1.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), s1);
}
}
wasn't really expecting it too work, but I gave it a go.
Another secondary question:
Is this the line of code which determines what IP and Port the server will be listening on?
_serverSocket.Bind(new IPEndPoint(IPAddress.Any, 100));
Used the same code, had the same problem.
It is not working because the client console is stuck in readLine(), so it is not receiving responses. After you send a command don't call Console.ReadLine again.
To loop trough all clients and send a message:
private static void sentToAll(string s)
{
foreach (Socket socket in clientSockets)
{
byte[] data = Encoding.ASCII.GetBytes(s);
socket.Send(data);
}
}
private static IPEndPoint localEndPoint;
public static String IpAddress = "10.0.0.13";
public static int port = 3000;
localEndPoint = new IPEndPoint(IPAddress.Parse(IpAddress), port);
_serverSocket.Bind(localEndPoint);