So I am having a very simple setup: A Server that waits for a Client to connect and a Client who connects to the Server and sends messages. The Server should afterwards send the same message back again. But when I try to send the message with client.SendAsync(sendArgs) it doesn't actually call the Completed Event on the sendArgs object even though I can see that my Server-Socket has already received all the bytes. So why is sendArgs.Completed in my Client-Socket not being raised, but receiveArgs.Completed in my Server-Socket class?
Namespaces used: System, System.Net, System.Net,System.Text
This is my code so far:
Client
public class SocketClient
{
public IPEndPoint Endpoint { get; }
private Socket client;
public SocketClient(IPAddress address, int port)
{
Endpoint = new IPEndPoint(address, port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void ConnectToServer(IPAddress serverAddress, int serverPort)
{
client.Bind(Endpoint);
try
{
client.Connect(serverAddress, serverPort);
}
catch (SocketException)
{
return;
}
}
public void SendMessage(string message)
{
SocketAsyncEventArgs sendArgs = new SocketAsyncEventArgs();
byte[] buffer = Encoding.ASCII.GetBytes(message);
sendArgs.SetBuffer(buffer, 0, buffer.Length);
sendArgs.Completed += SendArgs_Completed;
client.SendAsync(sendArgs);
}
private void SendArgs_Completed(object sender, SocketAsyncEventArgs e)
{
SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs();
byte[] buffer = new byte[1024];
receiveArgs.SetBuffer(buffer, 0, buffer.Length);
receiveArgs.Completed += ReceiveArgs_Completed;
client.ReceiveAsync(receiveArgs);
}
private void ReceiveArgs_Completed(object sender, SocketAsyncEventArgs e)
{
string message = Encoding.ASCII.GetString(e.Buffer);
Console.WriteLine(message);
}
}
Server
public class SocketServer
{
public IPEndPoint Endpoint { get; }
private Socket server;
public SocketServer(IPAddress address, int port)
{
Endpoint = new IPEndPoint(address, port);
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
public void Start()
{
server.Bind(Endpoint);
server.Listen(10);
SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += AcceptArgs_Completed;
server.AcceptAsync(acceptArgs);
}
private void AcceptArgs_Completed(object sender, SocketAsyncEventArgs e)
{
Socket connectionSocket = e.AcceptSocket;
SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs();
byte[] buffer = new byte[1024];
receiveArgs.SetBuffer(buffer, 0, buffer.Length);
receiveArgs.Completed += ReceiveArgs_Completed;
connectionSocket.ReceiveAsync(receiveArgs);
e.AcceptSocket = null;
server.AcceptAsync(e);
}
private void ReceiveArgs_Completed(object sender, SocketAsyncEventArgs e)
{
Socket connectionSocket = (Socket)sender;
SocketAsyncEventArgs sendArgs = new SocketAsyncEventArgs();
sendArgs.SetBuffer(e.Buffer, 0, e.Buffer.Length);
connectionSocket.SendAsync(sendArgs);
connectionSocket.ReceiveAsync(e);
}
}
Edit: I fixed it. The thing I was missing was to check if the SendAsync method has finished synchronously or asynchronously. If it finishes synchronously I need to call the event myself
bool completedAsync = client.SendAsync(sendArgs);
if(!completedAsync)
{
SendArgs_Completed(this, sendArgs);
}