System.Net.SocketException because of not connected Socket - c#

I'm new in Socket programming. I try to write an C# chat. Every time when i call this function:
void starteServer()
{
try {
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress localIpAddress = ipHostInfo.AddressList[0];
IPEndPoint localendpoint = new IPEndPoint(localIpAddress, serverPort);
server.Bind(localendpoint);
server.Listen(10);
Recive(server);
lb_chat.Items.Add(response);
receiveDone.WaitOne();
}
catch (Exception e)
{
errorHandler(e);
}
}
i get an System.Net.SocketException with the reason of an unconnected Socket. I think i breaks in the Recive(server)-line. This is the Recive Method:
private static void Recive(Socket client)
{
try
{
StateObjeckt state = new StateObjeckt();
state.workSocket = client;
client.BeginReceive(state.buffer, 0, StateObjeckt.bufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
errorHandler(e);
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
StateObjeckt state = (StateObjeckt)ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
client.BeginReceive(state.buffer, 0, StateObjeckt.bufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
receiveDone.Set();
}
}
hopefully someone can explain me this behavior and help me fix it.
if you need the rest of the code just visit:
https://gist.github.com/chrishennig/ea4b5a974fc6f9aa2bb6
Thanks in advance

Your problem is you are trying to read data from a listening socket, like it is the socket that is receiving data. When you Listen with a socket, it is only used for calling Accept to accept connections, and then those subsequent connected sockets are then read and written to. So, the exception is telling you that you are trying to read from a socket that isn't connected anywhere, which is correct since no sockets have yet been accepted.

Related

C# Socket: Server doesn't send messages

I'm making a communication via a socket but I'm having problems sending data from the server.
I'm able to send a response after receiving something but I need to be able to send a message without receiving anything from the client beforehand.
What I want to do is basically send a command over the socket after a connection is established. (after AcceptCallback() was called, which I check for). In my main program I have a button which I want to be able to click anytime to send a certain message. However, every time I try this I get an error that I cannot anything over an unconnected socket.
As you can see in the code I tried to send another message after receiving something from my client (see in the ReceiveCallback() where I send "Test send"). Sending that works, but if I want to send something else afterwards it again gives the error that I can't send something over a disconnected socket.
The current code looks like this(excerpts):
class SocketServer
{
private static Socket _serverSocket;
//Konstruktor
public SocketServer(int port = 9851)
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //Socket Objekt
lep = new IPEndPoint(IPAddress.Any, 9851);
}
private static void AcceptClient()
{
try
{
_serverSocket.Bind(lep);
_serverSocket.Listen(100);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket); //auf Verbindungen warten weiter bei AcceptCallback Methode
}
catch
{
...
}
}
private static void AcceptCallback(IAsyncResult AR) //Connection accept callback
{
try
{
Socket socket = _serverSocket.EndAccept(AR);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
}
catch (ObjectDisposedException e)
{
...
}
}
private static void ReceiveCallback(IAsyncResult AR)//Weiterführung Empfangen
{
Socket socket = (Socket)AR.AsyncState;
try
{
received = socket.EndReceive(AR); //Speichere Anzahl empfangener Bytes
... //trimming and saving the received data in a string
sending = "Test send";
byte[] data = Encoding.UTF8.GetBytes(sending);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket);
}
catch (ObjectDisposedException e)
{
...
}
}
public void SendMessage()
{
byte[] data = Encoding.UTF8.GetBytes(sending);
_serverSocket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), _serverSocket); //Beginnen des Sendevorgangs weiter bei SendCallback
...
}
private static void SendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
...
}
I've been working on this problem for over a week now. It's kind of hard to say what I tried before because I feel like I've tried everything and looked in the deepest part of the internet for help. So I'm standing before that possibilities that a)I am super blind somewhere, b) I'm overworked or c) it's actually impossible, sorry Rhino you need to scrap your project and start anew.
Anyway I'd be grateful for any kind of help. Thanks.
This is how I solved my problems:
The Problem was that I didn't use BeginSend(...) on the socket connection that I had used with EndAccept(), which was just named socket.
To be able to use this specific socket in any other method and not just the AcceptCallback(), I had to make it accessible.
I created a List to save Accepted sockets in called _clientSockets to which I added every accepted socket.
It now looks like this (only the parts that changed):
class SocketServer
{
private static Socket _serverSocket;
private static List<Sockets> _clientSockets=new List<Socket>();
private static void AcceptClient()
{
try
{
_serverSocket.Bind(lep);
_serverSocket.Listen(100);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket); //auf Verbindungen warten weiter bei AcceptCallback Methode
}
catch
{
...
}
}
private static void AcceptCallback(IAsyncResult AR) //Connection accept callback
{
try
{
Socket socket = _serverSocket.EndAccept(AR);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
_clientSockets.Add(socket); //This is the important part where I add the completed socket connection to the list!
}
catch
{
...
}
}
public void SendMessage(string sdata, int socketno)
{
Socket socket = _clientSockets[socketno] //Here I give the socket from before, or whichever one I choose, to this method to proceed with
byte[] data = Encoding.UTF8.GetBytes(sdata);
socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(SendCallback), socket); //Beginnen des Sendevorgangs weiter bei SendCallback
...
}
private static void SendCallback(IAsyncResult AR)
{
Socket socket = (Socket)AR.AsyncState;
socket.EndSend(AR);
...
}

C# - sending, reciving and then sending again via a socket

Me and my friend are making a basic client/server application, on two different computers. What we are trying to do :
1.I send him a string (as a server)
2 He sends me back another string,
I edit it and send it back.
But everytime we got to part 3 he doesn't recive anything my software just stops working and via debugging I end up with
"{"A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call"}
I'm pretty sure the fault is on my end, here are the functions that i'm using:
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
// handler.Close();
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
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);
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
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
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
// Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = s.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Get the rest of the data.
s.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
I connet with the client via
IPAddress ipAd = IPAddress.Parse("my_actual_ip_adress");
// use local m/c IP address, and
// use the same in the client
/* Initializes the Listener */
TcpListener myList = new TcpListener(ipAd, 8001);
/* Start Listeneting at the specified port */
myList.Start();
I realise that it probably sounds like a silly issue but we're having hard time coming up with actual solution, any help would me much appreciated
I managed to fix it! Turns out we needed get rid of handler.Shutdown(SocketShutdown.Both) and then change how the client recieve the data, since he was waiting for the socket to shutdown.
– some

Asynchronous client socket not receiving data

I try to implement my application with asynchronous socket communication. It perfectly connected and sent the request but I didn't receive any data from server (Java server). Socket connection is
client.BeginConnect(hostname, port,
new AsyncCallback(ConnectCallback), client);
connectDone.WaitOne();
private static void ConnectCallback(IAsyncResult ar) {
try {
// Retrieve the socket from the state object.
Socket client = (Socket) ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}",
client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
} catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
// Create the state object.
StateObject state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None,
new AsyncCallback(ReceiveCallback), client);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
Console.WriteLine(response);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
else
{
// All the data has arrived; put it in response.
if (state.sb.Length > 1)
{
response = state.sb.ToString();
}
// Signal that all bytes have been received.
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Any help would be appreciated.
Your code is almost ok, with one serious bug. In your BeginReceive, you put as the state object the client socket instance. In the ReceiveCallback function you cast it to a StateObject instead of a socket. This will cause an exception showing up at the console.
Nevertheless, also with this bug a breakpoint at the beginning of the ReceiveCallback function will trigger. Did you try this? The exception should have been thrown in any case.
In case that breakpoint doesn't trigger you should check independently whether something is really sent from the server. Of course all that assumed that the connection works, as you stated.

Clients and Server Listening for requests

I would like to know if my way of thinking is any good.
Here is sitution:
Server is accepting async for connections. After accept is recieveing async on accepted sockets.
Clients are connecting async to server, then listening for request async.
What I want to do is to send requests from both client and server. Other side should recieve it.
Server code:
public ServerHandler()
{
_serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(_ipLocal);
_serverSocket.Listen(4);
_serverSocket.BeginAccept(AcceptCallback, null);
}
private void AcceptCallback(IAsyncResult ar)
{
Socket socket = (Socket)ar.AsyncState;
_clients.Add(socket);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecieveCallback, socket);
_serverSocket.BeginAccept(AcceptCallback, null);
}
private void RecieveCallback(IAsyncResult ar)
{
var socket = (Socket) ar.AsyncState;
var recieved = socket.EndReceive(ar);
var dataBuff = new byte[recieved];
Array.Copy(_buffer, dataBuff, recieved);
OnMessageRecieved(dataBuff);
socket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecieveCallback, socket);
}
private void Send(byte[] data, Socket socket)
{
socket.BeginSend(data, 0, data.Length, SocketFlags.None,
SendCallback, socket);
}
private void SendCallback(IAsyncResult ar)
{
var socket = (Socket)ar.AsyncState;
socket.EndSend(ar);
}
private void SendToAll(byte[] data)
{
foreach (var clientSocket in _clients)
{
Send(data, clientSocket);
Debug.WriteLine("sent to: " + clientSocket.LocalEndPoint);
}
}
Client code:
public ClientHandler()
{
_ipLocal = new IPEndPoint(IPAddress.Parse(ServerIp), Port);
}
public void ConnectLoop()
{
int attempts = 0;
while (!_clientSocket.Connected)
{
try
{
attempts++;
_clientSocket.BeginConnect(IPAddress.Parse(ServerIp), Port, ConnectCallback, null);
_clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecieveCallback,
_clientSocket);
}
catch (Exception)
{
Debug.WriteLine("Connection attempts: " + attempts);
}
}
Debug.WriteLine("Connected");
}
private void ConnectCallback(IAsyncResult ar)
{
_clientSocket.EndConnect(ar);
}
private void RecieveCallback(IAsyncResult ar)
{
var socket = (Socket) ar.AsyncState;
int recieved = _clientSocket.EndReceive(ar);
var dataBuff = new byte[recieved];
Array.Copy(_buffer, dataBuff, recieved);
OnMessageRecieved(dataBuff);
_clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, RecieveCallback, _clientSocket);
}
private void Send(byte[] data, Socket socket)
{
socket.BeginSend(data, 0, data.Length, SocketFlags.None,
SendCallback, socket);
}
private void SendCallback(IAsyncResult ar)
{
var socket = (Socket)ar.AsyncState;
socket.EndSend(ar);
}
Will sth like this work?
EDIT1: Oh, and I want to do it through 1 socket. Client/server sending and recieveing on same socket. But there can be multiple clients sockets, but only 1 for pair client-server.
Without testing, your code looks alright however, you'll need to provide extra code to determine if you've got a whole message or not.
When you do a read, you may get one of the following scenarios:
Some of a message, but not all
exactly all of a message
all of a message plus some/all of another message
a socket error (disconnected etc).
There are a few generally accepted methods of determining what a whole message is:
delimiting your message so your receival code needs to look for the delimiters
A fixed message size with some sort of embedding to indicate if there are more messages
a variable message size but with a fixed "size" part which is transmitted first Ie say the first 4 bytes will indicate the size of the message. So you know you always need 4 bytes first to determine the length of the message; and then you know how much to process for the next message.
This SO post Chat service application has some more and links on processing messages.

Asynchronous Sockets Receive/Send doesn't receive/send the first byte

I'm trying to make a basic chat system for multiple people.
It sends messages and all, but except the first message sent from each client, each message's first byte is missing (whether the client didn't send it, or the server did not receive it).
Here is my client's Send and SendCallback:
private static void Send(Socket client, string data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket) ar.AsyncState;
int bytesSent = client.EndSend(ar);
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
And here's my server's Accepter and ReceiveCallback:
private static void AcceptCallback(IAsyncResult ar)
{
allDone.Set();
Socket listenerSocket = (Socket) ar.AsyncState;
Socket handlerSocket = listenerSocket.EndAccept(ar);
if (!clientList.Contains(handlerSocket))
{
clientList.Add(handlerSocket);
}
// Creating the state object
StateObject state = new StateObject();
state.workSocket = handlerSocket;
handlerSocket.BeginReceive(state.buffer, 0, StateObject.BUFFER_SIZE, 0,
new AsyncCallback(ReceiveCallback), state);
}
private static void ReceiveCallback(IAsyncResult ar)
{
StateObject state = (StateObject) ar.AsyncState;
Socket handlerSocket = state.workSocket;
// Read data from the client socket.
try
{
int read = handlerSocket.EndReceive(ar);
if (read > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, read));
handlerSocket.BeginReceive(state.buffer, 0, StateObject.BUFFER_SIZE, 0, new AsyncCallback(ReceiveCallback),
state);
}
if (state.sb.Length > 0)
{
string content = state.sb.ToString();
foreach (Socket clientSocket in clientList)
{
Send(clientSocket, content);
}
Console.WriteLine(content);
state.sb = new StringBuilder();
}
else
handlerSocket.Close();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
I'll give an example of the problem:
client sends "hi",
server sees "hi" - everything is fine.
then:
client sends "hi"
server sees "i" - first character is missing.
What am I missing? What did I do wrong?

Categories