⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpudpclient.cs

📁 WinChat was created in late 2000 by Spectre, DeMENted and Unique_T. You can connect to WinChat.Ne
💻 CS
字号:
/* File        :  TcpUdpClient.cs
 * Namespace   :  ClientServer
 * Classes     :  TcpUdpClient
 */
namespace ClientServer
{
	/* Class			: TcpUdpClient
	 * Base Class		: None
	 * Functionality	: Handles all the client side functionalities including:
	 *                    1.  Creates a TcpClient to be used during the chat session;
	 *                    2.  Creates a UdpClient to send all the call initiation messages like
	 *                        NOTIFY REQUEST and NOTIFY HANGUP REQUEST.
	 */

	using System;
	using System.Net;
	using System.Net.Sockets;
	using System.Threading;
	using System.Windows.Forms;
	using System.Timers;
	
	public class TcpUdpClient
	{
		private NetworkStream tcpStream;

		private UdpClient udpNotifyClient;

		private System.Timers.Timer notifyTimer;
		
		public TcpClient tcpClient;

		public TcpUdpClient()
		{
		}

		/* Function     : createTcpClientConnection(String serverName)
		 * Purpose      : This function will create a TCP connection to the given serverName and
		 *                the well known TCP Port (4567).  
		 * Algorithm    : It creates a TcpClient instance to the serverName and SAMPLETCPPORT,
		 *                set the LingerOption.  It also assigns a TCP stream to tcpStream so that
		 *                the TcpClient can use to send data later on.
		 */

		public void createTcpClientConnection(String serverName)
		{
			try
			{
				//Create an instance of TcpClient.
				tcpClient = new TcpClient(serverName, ClientServerConstants.SAMPLETCPPORT);

				//Make sure the TcpClient will be closed right away when TcpClient.Close() is called.
				LingerOption tcpClientLingerOption = new LingerOption(false,0);

				tcpClient.LingerState = tcpClientLingerOption;

				//Get the NetworkStream for this tcpClient instance.
				tcpStream = tcpClient.GetStream();

			}
			catch (Exception e)
			{
				MessageBox.Show("An Exception has occurred!" + e.ToString(), "WinChat", 
					MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
		}

		/* Function     : tcpClientSendMessage(String whatEver)
		 * Purpose      : This function will send a message "whatEver" using the tcpStream. 
		 * Algorithm    : The tcpstream is assigned from the createTcpClientConnection()
		 *                function.  First, it makes sure whether the tcpStream is writable.
		 *                if so, it converts the whatEver string to a byte array by 
		 *                System.Text.Encoding.ASCII.GetBytes(whatEver.ToCharArray()).  After
		 *                that, it flushes the byte array to the tcpStream.
		 */
		public void tcpClientSendMessage(String whatEver)
		{
			try
			{
				if (tcpStream.CanWrite)
				{
					Byte[] inputToBeSent = System.Text.Encoding.ASCII.GetBytes(whatEver.ToCharArray());
										
					tcpStream.Write(inputToBeSent, 0, inputToBeSent.Length);

					tcpStream.Flush();
				}
			}
			catch (SocketException se)
			{
				MessageBox.Show("A Socket Exception has occurred!" + se.ToString(), "WinChat", 
					MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}

		}

		/* Function     : tcpClientSendMessage(String whatEver)
		 * Purpose      : This function will simply close the tcpClient. 
		 *
		 */
		public void closeTcpClientConnection()
		{
			try
			{
				tcpClient.Close();
			}
			catch (SocketException se)
			{
				MessageBox.Show("A Socket Exception has occurred!" + se.ToString(), "WinChat", 
					MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
		}


		/* Function     : sendNotify(String serverName, String eventToNotify)
		 * Return       : boolean
		 * Purpose      : This function will send a notification message to the UDP server 
		 *                at "serverName" and the UDP well known port (UDPNOTIFYPORT).
		 * Algorithm    : This function first creates a UdpClient instance (udpNotifyClient)
		 *                that will send the string "eventToNotify" to "serverName" and the 
		 *                well known port(UDPNOTIFYPORT).  It will then wait for the response
		 *                returned by the remote peer.
		 *                According to the response received from the remote peer, this function
		 *                will take different action:
		 * 
		 *	              1.  If the remote peer accepts the call request, the function will 
		 *                    return true and the chat session can begin.  
		 *				  2.  If the "eventToNotify" is notifyHangupRequest, and the response is
		 *                    notifyHangupAccept, the function will return true and the chat
		 *                    session will terminate gracefully.
		 *                3.  Any other response prompts the function to return false.
		 * 
		 *                As soon as the "eventToNotify" is sent, a 30 seconds Notify Timer 
		 *                will be started.  This timer is used to make sure that the tcpClient
		 *                will get a response from the remote peer (whether he/she wants to chat
		 *                or not) within 30 seconds.  If the timer expires, a MessageBox will pop
		 *                up to notify the local user that the remote peer did not respond
		 *                promptly.  When it receives a response from the remote peer, the timer 
		 *                will be stopped.
		 *               
		 */
		public bool sendNotify(String serverName, String eventToNotify)
		{
			Byte[] receivedNotify = new Byte[64];

			try
			{
				//Create an instance of UdpClient.
				udpNotifyClient = new UdpClient(serverName, ClientServerConstants.UDPNOTIFYPORT);

				Byte[] inputToBeSent = new Byte[64];

				//Convert the "eventToNotify" string to a byte array, and then send it to
				//the remote UDP server using udpNotifyClient.
				inputToBeSent = System.Text.Encoding.ASCII.GetBytes(eventToNotify.ToCharArray());

				int nBytesSent = udpNotifyClient.Send(inputToBeSent, inputToBeSent.Length);

				//Start the Notify Timer to make sure that the remote peer will respond within 
				//a 30 seconds time frame.
				this.startNotifyTimer();

				IPHostEntry remoteNotifyHostEntry = Dns.GetHostByName(serverName);
			
				IPEndPoint remoteNotifyIpEndPoint = new IPEndPoint(remoteNotifyHostEntry.AddressList[0], 
					ClientServerConstants.UDPNOTIFYPORT);

				//Call Receive() to "wait" for the remote peer's response.  As soon as the response
				//is received, stop the timer.
				receivedNotify = udpNotifyClient.Receive(ref remoteNotifyIpEndPoint);
				//There is a known issue here.  After the timer expires, the udpNotifyClient will be
				//closed.  This will prompt an exception message to pop up because the socket that
				//the udpNotifyClient is bound on will be closed too.  However, this won't affect the 
				//program in anyway.
				
				this.stopNotifyTimer();
			}
			catch (SocketException se)
			{
				if (se.ErrorCode == 11004)
				{
					MessageBox.Show("Unknown host.  Please check the hostname or IP address and try again.", 
						"WinChat", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				}
				//ErrorCode 10054 corresponds to the exception: An existing connection is forcibly
				//closed by the remote host.  This happens when the remote host does not have 
				//WinChat for .Net running.  This exception shouldn't stop the processing.
				if ((se.ErrorCode != 10054) && (se.ErrorCode != 10038))
				{
					MessageBox.Show("A Socket Exception has occurred!" + se.ToString(), "WinChat", 
						MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				}
			}
			catch (Exception e)
			{
				MessageBox.Show("An Exception has occurred!" + e.ToString(), "WinChat", 
					MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}

			String dataReceivedNotify = System.Text.Encoding.ASCII.GetString(receivedNotify);

			switch (dataReceivedNotify)
			{
				case ClientServerConstants.notifyAccept:
				{
					//The remote peer accepts the call request.  The chat session can now begin.
					MessageBox.Show("The other party accepted your call request.  You can start talking now.", 
						"WinChat", MessageBoxButtons.OK);
					return true;
				}
				case ClientServerConstants.notifyUnknownReject:
				{
					//The response from the remote peer is not recognized as one of the possible response.
					//The chat session cannot begin.
					MessageBox.Show("There was some network problem.  Please try again.", "WinChat",
						MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return false;
				}
				case ClientServerConstants.notifyReject:
				{
					//The remote peer rejects the call request.  The chat session cannot begin.
					MessageBox.Show("The party your are calling rejects your call.", "WinChat",
						MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return false;
				}
				case ClientServerConstants.notifyHangupAccept:
				{
					//The notifyHangupAccept would only be received when the eventToNotify was
					//notifyHangupRequest.  If not, some data might have been lost in the network.
					if (eventToNotify.Equals(ClientServerConstants.notifyHangupRequest)) 
						return true;
					else
						return false;
				}
				case ClientServerConstants.notifyAlreadyTalking:
				{
					//The remote peer is in 'alreadyTalking" mode.  The chat session cannot begin.
					MessageBox.Show("The party you are calling is busy at this moment.", "WinChat",
						MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return false;
				}
				default:
				{
					return false;
				}
			}
		}

		/* Function     : startNotifyTimer()
		 * Return       : void
		 * Purpose      : This function will start the Notify Timer.
		 */
		public void startNotifyTimer()
		{       
			// Create a new Timer with Interval set to 20 seconds.
			notifyTimer = new System.Timers.Timer(ClientServerConstants.UDPTIMER);
			notifyTimer.Elapsed += new ElapsedEventHandler(this.OnTimedEvent);
			// Only raise the event the first time Interval elapses.
			notifyTimer.AutoReset = false;
			notifyTimer.Enabled = true;
		}

		/* Function     : stopNotifyTimer()
		 * Return       : void
		 * Purpose      : This function sill stop the Notify Timer.
		 */
		public void stopNotifyTimer()
		{
			notifyTimer.Stop();
		}

		/* Function     : OnTimedEvent(object source, ElapsedEventArgs e) 
		 * Return       : void
		 * Purpose      : This function sill close the udpNotifyClient when the Notify
		 *                Timer expires.
		 */
		public void OnTimedEvent(object source, ElapsedEventArgs e) 
		{
			try
			{
				MessageBox.Show("The party you are calling does not respond.", "WinChat",
					MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

				udpNotifyClient.Close();
			}
			catch (Exception ex)
			{
				MessageBox.Show("An Exception has occurred!" + ex.ToString(), "WinChat", 
					MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
		}
	}
}

// created on 8/26/2001 at 1:21 PM

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -