Eigene Dateien/Visual Studio 2005/Projects/DCPlusPlus/DCPlusPlus/ListeningSockets.cs

Go to the documentation of this file.
00001 using System;
00002 using System.Collections.Generic;
00003 using System.Text;
00004 using System.Net;
00005 using System.Net.Sockets;
00006 using System.Threading;
00007 
00008 namespace DCPlusPlus
00009 {
00016     public class ListeningSockets
00017     {
00022         public delegate void SearchResultReceivedEventHandler(SearchResults.SearchResult result);
00027         public event SearchResultReceivedEventHandler SearchResultReceived;
00032         public event Peer.ConnectedEventHandler PeerConnected;
00033         protected string ip = "";
00037         public string IP
00038         {
00039             get
00040             {
00041                 return (ip);
00042             }
00043         }
00044         protected string external_ip = "";
00049         public string ExternalIP
00050         {
00051             get
00052             {
00053                 return (external_ip);
00054             }
00055             set
00056             {
00057                 external_ip = value;
00058             }
00059         }
00060         protected int tcp_port = 0;//TODO change this to a certain port as default,else we may clutter up a routers upnp port mappings
00065         public int TcpPort
00066         {
00067             get
00068             {
00069                 return (tcp_port);
00070             }
00071             set
00072             {
00073                 tcp_port = value;
00074             }
00075         }
00076         protected int udp_port = 0;
00081         public int UdpPort
00082         {
00083             get
00084             {
00085                 return (udp_port);
00086             }
00087             set
00088             {
00089                 udp_port = value;
00090             }
00091 
00092         }
00093         protected int max_tcp_connections = 100;
00097         public int MaxTcpConnections
00098         {
00099             get
00100             {
00101                 return (max_tcp_connections);
00102             }
00103             set
00104             {
00105                 max_tcp_connections = value;
00106             }
00107         }
00108         /* this is one for the books lol a max connections int for a connectionless protocol
00109          * think first before writing ;-)
00110         protected int max_udp_connections = 100;
00114         public int MaxUdpConnections
00115         {
00116             get
00117             {
00118                 return (max_udp_connections);
00119             }
00120             set
00121             {
00122                 max_udp_connections = value;
00123             }
00124         }
00125         
00129         public int MaxConnections
00130         {
00131             get
00132             {
00133                 return (max_tcp_connections + max_udp_connections);
00134             }
00135             set
00136             {
00137                 max_udp_connections = value / 2;
00138                 max_tcp_connections = value / 2;
00139             }
00140         }*/
00146         public ListeningSockets()
00147         {
00148             UpdateIP();
00149             SetupListeningSocket();
00150         }
00155         private void UpdateIP()
00156         {
00157             string host_name = Dns.GetHostName();
00158             IPHostEntry host_entry = Dns.GetHostEntry(host_name);
00159             if (host_entry.AddressList.Length == 0) return;//computer has not one network interface ;-( i bet this one will never a case anywhere, but better catch it *g*
00160             ip = host_entry.AddressList[0].ToString();
00161         }
00162         protected bool listening = false;
00166         public bool IsListening
00167         {
00168             get
00169             {
00170                 return (listening);
00171             }
00172         }
00177         private Socket tcp_socket = null;
00182         private IAsyncResult tcp_callback = null;
00187         private Socket udp_socket = null;
00191         private byte[] receive_from_buffer = new byte[1024];
00196         private IPEndPoint receive_from_endpoint = new IPEndPoint(IPAddress.None, 0);
00202         public void UpdateConnectionSettings()
00203         {
00204             if (listening)
00205                 CloseListeningSocket();
00206             SetupListeningSocket();
00207         }
00212         ~ListeningSockets()
00213         {
00214             CloseListeningSocket();
00215         }
00219         public void Close()
00220         {
00221             CloseListeningSocket();
00222         }
00227         private void CloseListeningSocket()
00228         {
00229             //close the listening socket if openened
00230             lock (listening_lock)
00231             {
00232                 if (listening)
00233                 {
00234                     listening = false;
00235                     try
00236                     {
00237                         if (udp_socket != null)
00238                         {
00239                             udp_socket.ReceiveTimeout = 0;
00240                             //udp_socket.Shutdown(SocketShutdown.Both);
00241                             //Thread.Sleep(10);
00242                             udp_socket.Close();
00243                             //Thread.Sleep(10);
00244                             udp_socket = null;
00245                             Thread.Sleep(10);
00246                             Console.WriteLine("Closed Listening udp socket.");
00247                         }
00248                         if (tcp_socket != null)
00249                         {
00250                             //int temp_timeout = tcp_socket.ReceiveTimeout;
00251                             //tcp_socket.Shutdown(SocketShutdown.Both);
00252                             //tcp_socket
00253                             tcp_socket.ReceiveTimeout = 0;
00254                             tcp_socket.Close();
00255                             //Thread.Sleep(10);
00256                             tcp_socket = null;
00257                             Thread.Sleep(10);
00258                             Console.WriteLine("Closed Listening tcp socket.");
00259                         }
00260 
00261                     }
00262                     catch (Exception ex)
00263                     {
00264                         Console.WriteLine("Error closing listening socket: " + ex.Message);
00265                     }
00266                 }
00267             }
00268         }
00272         private object listening_lock = new Object();
00277         private void SetupListeningSocket()
00278         {
00279             //if ip is nullorempty
00280             //if ports == 0
00281             //determine local ip address
00282             //select random ports
00283             //
00284             // setup socket accordingly
00285             lock (listening_lock)
00286             {
00287                 if (!listening)
00288                 {
00289                     listening = true;
00290                     if (tcp_socket == null)
00291                     {
00292                         try
00293                         {
00294                             tcp_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
00295                             IPEndPoint tcp_local_endpoint = new IPEndPoint(IPAddress.Any, tcp_port);
00296                             tcp_socket.Bind(tcp_local_endpoint);
00297                             tcp_port = ((IPEndPoint)tcp_socket.LocalEndPoint).Port;
00298                             tcp_socket.Blocking = false;
00299                             //tcp_socket.LingerState = new LingerOption(false, 0);
00300                             tcp_socket.Listen(max_tcp_connections);
00301                             AsyncCallback event_accept = new AsyncCallback(OnAccept);
00302                             tcp_callback = tcp_socket.BeginAccept(event_accept, tcp_socket);
00303                             Console.WriteLine("Bound listening tcp socket to port: " + tcp_port);
00304                         }
00305                         catch (Exception ex)
00306                         {
00307                             Console.WriteLine("Exception opening local peer tcp port");
00308                         }
00309                     }
00310                     else Console.WriteLine("tcp port already in use :" + tcp_port);
00311                     if (udp_socket == null)
00312                     {
00313                         try
00314                         {
00315                             udp_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
00316                             IPEndPoint udp_local_endpoint = new IPEndPoint(IPAddress.Any, udp_port);
00317                             udp_socket.Bind(udp_local_endpoint);
00318                             udp_port = ((IPEndPoint)udp_socket.LocalEndPoint).Port;
00319                             udp_socket.Blocking = false;
00320                             //udp_socket.LingerState = new LingerOption(false, 0);
00321                             EndPoint temp_receive_from_endpoint = (EndPoint)receive_from_endpoint;
00322                             AsyncCallback event_receive_from = new AsyncCallback(OnReceiveFrom);
00323                             udp_socket.BeginReceiveFrom(receive_from_buffer, 0, receive_from_buffer.Length, SocketFlags.None, ref temp_receive_from_endpoint, event_receive_from, udp_socket);
00324                             Console.WriteLine("Bound UDP-Channel to port: " + udp_port);
00325                         }
00326                         catch (Exception ex)
00327                         {
00328                             Console.WriteLine("Exception opening local peer udp port");
00329                         }
00330 
00331                     }
00332                     else Console.WriteLine("udp port already in use :" + udp_port);
00333                 }
00334             }
00335         }
00340         private void OnReceiveFrom(IAsyncResult result)
00341         {
00342             if (udp_socket != null)
00343             {
00344                 if (!udp_socket.IsBound) return;
00345                 try
00346                 {
00347                     if (udp_socket != ((Socket)result.AsyncState)) return;
00348                     Socket receive_from_socket = (Socket)result.AsyncState;
00349                     if (receive_from_socket == null) return;
00350                     //if (!receive_from_socket.IsBound) return;
00351                     //Socket receive_from_socket = (Socket)result;
00352                     //Console.WriteLine("udp packet received.");
00353                     EndPoint temp_receive_from_endpoint = (EndPoint)receive_from_endpoint;
00354                     //Console.WriteLine("udp packet end start.");
00355                     int received_bytes = udp_socket.EndReceiveFrom(result, ref temp_receive_from_endpoint);
00356                     //Console.WriteLine("udp packet end end.");
00357 
00358                     if (received_bytes > 0)
00359                     {
00360                         //string received_string = Encoding.ASCII.GetString(receive_from_buffer, 0, received_bytes);
00361                         string received_string = System.Text.Encoding.Default.GetString(receive_from_buffer, 0, received_bytes);
00362                         //Console.WriteLine("received data in packet: " + received_string);
00363                         InterpretReceivedString(received_string);
00364                     }
00365                     else Console.WriteLine("Empty packet received");
00366 
00367                     //Console.WriteLine("udp packet begin start.");
00368                     //Console.WriteLine("udp packet begin end.");
00369                 }
00370                 //catch (ObjectDisposedException oex)
00371                 //{
00372                 //}
00373                 catch (Exception ex)
00374                 {
00375                     Console.WriteLine("Error in ReceiveFrom callback: " + ex.Message);
00376                 }
00377                 try
00378                 {
00379                     EndPoint temp_receive_from_endpoint = (EndPoint)receive_from_endpoint;
00380                     AsyncCallback event_receive_from = new AsyncCallback(OnReceiveFrom);
00381                     udp_socket.BeginReceiveFrom(receive_from_buffer, 0, receive_from_buffer.Length, SocketFlags.None, ref temp_receive_from_endpoint, event_receive_from, udp_socket);
00382                 }
00383                 catch (Exception ex)
00384                 {
00385                     Console.WriteLine("Fatal Error in ReceiveFrom callback: " + ex.Message);
00386                 }
00387 
00388             
00389             }
00390             else Console.WriteLine("ReceiveFrom on udp socket aborted.");
00391         }
00400         private void InterpretReceivedString(string received_string)
00401         {
00402             // possible strings
00403             //$command|
00404             //<chat>
00405             //| 
00406             string[] received_strings = received_string.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
00407             for (int i = 0; i < received_strings.Length; i++)
00408             {
00409                 //if (received_strings[i].StartsWith("<")) Console.WriteLine("chat message on hub: " + name + " - " + received_strings[i]);
00410                 if (received_strings[i].StartsWith("$")) InterpretCommand(received_strings[i]);
00411                 else Console.WriteLine("Received a non command line: " + received_strings[i]);
00412             }
00413          
00414         }
00420         private void InterpretCommand(string received_command)
00421         {
00422             int command_end = received_command.IndexOf(" ");
00423             if (command_end != -1)
00424             {
00425                 string command = received_command.Substring(1, command_end - 1);
00426                 string parameter = received_command.Substring(command_end + 1);
00427                 string[] parameters = parameter.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
00428                 //Console.WriteLine("Command: '" + command + "' ,Parameter("+parameters.Length+"): '" + parameter + "'");
00429 
00430                 switch (command)
00431                 {
00432                     case "SR":
00433                         //Console.WriteLine("Search result received: " + parameter);
00434                         SearchResults.SearchResult result = new SearchResults.SearchResult();
00435                         result.ResultLine = parameter;
00436                         try
00437                         {
00438                             if (SearchResultReceived != null)
00439                                 SearchResultReceived( result);
00440                         }
00441                         catch (Exception ex)
00442                         {
00443                             Console.WriteLine("Exception in event handler: " + ex.Message);
00444                         }
00445 
00446                         break;
00447 
00448 
00449                     default:
00450                         Console.WriteLine("Unknown Command received: " + command + ", Parameter: " + parameter);
00451                         break;
00452                 }
00453             }
00454             else Console.WriteLine("Error interpreting command: " + received_command);
00455         }
00460         private void OnAccept(IAsyncResult result)
00461         {
00462             if (tcp_socket != null)
00463             {
00464                 //if(
00465                 if (!tcp_socket.IsBound) return;
00466                 if (!result.IsCompleted) return;
00467                 try
00468                 {
00469 
00470                     if (tcp_socket != ((Socket)result.AsyncState)) return;
00471                     Socket accept_socket = (Socket)result.AsyncState;
00472                     if (accept_socket == null) return;
00473                     if (!accept_socket.IsBound) return;
00474                     //if (!accept_socket.Connected) return;
00475                     //Console.WriteLine("trying end accept.");
00476                     //accept_socket.a
00477                     Socket client = tcp_socket.EndAccept(result);
00478                     if (!client.Connected) return;
00479                     //Console.WriteLine("new client connected.");
00480                     Peer new_peer = new Peer(client);
00481                     try
00482                     {
00483                         if (PeerConnected != null)
00484                         {
00485                             PeerConnected(new_peer);
00486                         }
00487                     
00488                     }
00489                     catch (Exception ex)
00490                     {
00491                         Console.WriteLine("Exception in Peer Connected Event: " + ex.Message);
00492                     }
00493                             
00494                     //accept_socket.Close();
00495                 }
00496                 catch (Exception ex)
00497                 {
00498                     Console.WriteLine("Error accepting connection: " + ex.Message);
00499                 }
00500                 try
00501                 {
00502                     AsyncCallback event_accept = new AsyncCallback(OnAccept);
00503                     tcp_socket.BeginAccept(event_accept, tcp_socket);
00504                 }
00505                 catch (Exception ex)
00506                 {
00507                     Console.WriteLine("Fatal Error accepting connection: " + ex.Message);
00508                 }
00509 
00510 
00511             }
00512             else Console.WriteLine("Accept on tcp socket aborted.");
00513         }
00522         public void SearchReply(string result_name, long filesize, Hub hub, Hub.SearchParameters search)
00523         {
00524             try
00525             {
00526             string temp_hub = hub.Name;
00527             if (search.HasTTH) temp_hub = "TTH:" + search.tth;
00528             string reply = "$SR " + hub.Nick + " " + result_name + (char)0x05 + filesize + " 1/1" + (char)0x05 + temp_hub + " (" + hub.IP + ":" + hub.Port + ")|";
00529             Console.WriteLine("Replying to active search: " + reply);
00530             IPEndPoint udp_reply_endpoint = new IPEndPoint(IPAddress.Parse(search.ip), search.port);
00531             //EndPoint temp_receive_from_endpoint = (EndPoint)receive_from_endpoint;
00532             
00533             byte[] send_bytes = System.Text.Encoding.Default.GetBytes(reply);
00534             udp_socket.BeginSendTo(send_bytes, 0, send_bytes.Length, SocketFlags.None,udp_reply_endpoint, new AsyncCallback(SearchReplyCallback), udp_socket);
00535             }
00536             catch(Exception ex)
00537             {
00538                 Console.WriteLine("Exception during sending of SearchReply to: "+search.ip+":"+search.port+" : "+ex.Message);
00539             }
00540         }
00545         protected void SearchReplyCallback(IAsyncResult ar)
00546         {
00547             Socket search_reply_socket = (Socket)ar.AsyncState;
00548             try
00549             {
00550                 int bytes_sent = search_reply_socket.EndSend(ar);
00551 
00552             }
00553             catch (Exception ex)
00554             {
00555                 Console.WriteLine("exception during sending of SearchReply: " + ex.Message);
00556             }
00557         }
00558     }
00559 }

Generated on Wed Mar 7 19:09:20 2007 for DCPlusPlus by  doxygen 1.5.1-p1