I tried to socket programming with AcceptAsync and SocketAsyncEventArgs. I wrote my code if Client access to Server, AcceptAsync make completed event and try to receive. But when I try. Client Socket completly access to Server Socket. But Server's AcceptAsync return 'true' and don't make Completed Event. By the way, In Debug Mode, AcceptAsync's blocking is true and AcceptAsync return 'false' and Client and Server Socket send and recv each other by manually call OnAccecptCompleted Method.
I tried to this similar Questioin's Solution.
My Server Code is this :
Socket _listenerSocket;
Action<Socket> _onAcceptHandler;
public void Init(IPEndPoint endPoint, Action<Socket> onAcceptHandler) {
Console.WriteLine("Init");
_listenerSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_onAcceptHandler += onAcceptHandler;
_listenerSocket.Bind(endPoint);
_listenerSocket.Listen(10);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.SetBuffer(null, 0, 0);
args.Completed += new EventHandler<SocketAsyncEventArgs>(OnAccecptCompleted);
RegisterAccept(args);
}
void RegisterAccept(SocketAsyncEventArgs args) {
Console.WriteLine("RegisterAccept");
args.AcceptSocket = null;
try {
bool pending = _listenerSocket.AcceptAsync(args);
Console.WriteLine($"pending {pending}");
if (pending == false) {
Console.WriteLine("RegisterAccept_pending==false");
OnAccecptCompleted(null, args);
}
}
catch(Exception e) {
Console.WriteLine(e.ToString);
}
}
void OnAccecptCompleted(object sender, SocketAsyncEventArgs args) {
Console.WriteLine("OnAcceptCompleted");
if(args.SocketError == SocketError.Success) {
_onAcceptHandler.Invoke(args.AcceptSocket);
}
else {
Console.WriteLine(args.SocketError.ToString());
}
RegisterAccept(args);
}
My endPoint arg's Code is this :
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);
My OnAcceptHandler Method code is this :
static void OnAcceptHandler(Socket clientSocket) {
try {
// Recv
byte[] recvBuff = new byte[1024];
int recvByte = clientSocket.Receive(recvBuff);
string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvByte);
Console.WriteLine($"[From Client] : {recvData}");
// Send
byte[] sendBuff = Encoding.UTF8.GetBytes("Welcome to Server!");
clientSocket.Send(sendBuff);
// DisConnect
//clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
catch(Exception e) {
Console.WriteLine(e.ToString());
}
}
When AcceptAsync don't make 'Completed Event', My socket status is like this.
Add 01 : I fix this problem but It just temporary solution. After Init() I tried to Thread.Sleep(), Send / Recv Problem is fixed. I don't know why but it works. If someone know why this happen or guess why, please comment under this question. Thanks.
Add 02 : If Thread.Sleep()'s time is low, Socket communicate is stop on Client's Socket.Recv part and Server's AcceptAsync doesn't make Completed Event.
Fixed Server's Main() :
static void Main(string[] args) {
// DNS
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);
//Console.WriteLine($"host : {host}, ipHost : {ipHost}, ipAddr : {ipAddr}, endPoint : {endPoint.Address}");
// set Listener Socket
_listener.Init(endPoint, OnAcceptHandler);
Console.WriteLine("Listening...");
Thread.Sleep(2000);
//Console.WriteLine(_listener.args.SocketError );
while (true) {
;
}
}
- Add 03 : if Thread.Sleep Work in While(), It Client and Sernver's communicatioin is never stop.(sometimes delay but never stop)
This is Fixed code :
static void Main(string[] args) {
// DNS
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);
//Console.WriteLine($"host : {host}, ipHost : {ipHost}, ipAddr : {ipAddr}, endPoint : {endPoint.Address}");
// set Listener Socket
_listener.Init(endPoint, OnAcceptHandler);
Console.WriteLine("Listening...");
//Console.WriteLine(_listener.args.SocketError );
while (true) {
Thread.Sleep(1);
}
}
I guess this is Mac's work assign Policy issue. Am I right?