问题描述
我正在尝试一个演示项目:
http://code.msdn.microsoft.com/Communication-through-91a2582b
我做了一些小事在VS 2008中更改。服务器代码如下:
I am trying the a demo project from:
http://code.msdn.microsoft.com/Communication-through-91a2582b
I have made some small change in VS 2008. The server code is following:
using System;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace TCP_Socket_Server
{
public partial class TCPSocketServer : Form
{
SocketPermission permission;
Socket sListener;
IPEndPoint ipEndPoint;
Socket handler;
private TextBox tbAux = new TextBox();
public TCPSocketServer()
{
InitializeComponent();
tbAux.TextChanged += tbAux_SelectionChanged;
button_ServerStart.Enabled = true;
button_Send.Enabled = false;
button_Disconnect.Enabled = false;
textBox_MessageReceived.Enabled = false;
textBox_Message2Client.Enabled = false;
}
private void tbAux_SelectionChanged(object sender, EventArgs e)
{
BeginInvoke((ThreadStart)delegate()
{
textBox_MessageReceived.Text = tbAux.Text;
label_MessageReceived.Text = "Received Message(" + (2*tbAux.Text.Length).ToString() +"Byte)";
}
);
}
private void button_ServerStart_Click(object sender, EventArgs e)
{
int servPort = (textBox_Port.Text.Length != 0) ? Int32.Parse(textBox_Port.Text) : 8821;
try
{
// Creates one SocketPermission object for access restrictions
permission = new SocketPermission(NetworkAccess.Accept, TransportType.Tcp, "", servPort );
// Listening Socket object
sListener = null;
// Ensures the code to have permission to access a Socket
permission.Demand();
// Resolves a host name to an IPHostEntry instance
IPHostEntry ipHost = Dns.GetHostEntry("");
// Gets first IP address associated with a localhost
IPAddress ipAddr = ipHost.AddressList[0];
// Creates a network endpoint
ipEndPoint = new IPEndPoint(ipAddr, servPort);
// Create one Socket object to listen the incoming connection
sListener = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp );
sListener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
// Associates a Socket with a local endpoint
sListener.Bind(ipEndPoint);
label_ServerState.Text = "Server Started:" + ipEndPoint.Address + ":" + ipEndPoint.Port;;
label_ServerState.ForeColor = Color.Blue;
button_Send.Enabled = true;
button_Disconnect.Enabled = true;
textBox_MessageReceived.Enabled = true;
textBox_Message2Client.Enabled = true;
// Places a Socket in a listening state and specifies the maximum
// Length of the pending connections queue
sListener.Listen(10);
// Begins an asynchronous operation to accept an attempt
AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
sListener.BeginAccept(aCallback, sListener);
button_ServerStart.Enabled = false;
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
public void AcceptCallback(IAsyncResult ar)
{
Socket listener = null;
// A new Socket to handle remote host communication
Socket handler = null;
try
{
// Receiving byte array
byte[] buffer = new byte[1024];
// Get Listening Socket object
listener = (Socket)ar.AsyncState;
// Create a new socket
handler = listener.EndAccept(ar);
// Using the Nagle algorithm
handler.NoDelay = false;
// Creates one object array for passing data
object[] obj = new object[2];
obj[0] = buffer;
obj[1] = handler;
// Begins to asynchronously receive data
handler.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), obj);
// Begins an asynchronous operation to accept an attempt
AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
listener.BeginAccept(aCallback, listener);
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
public void ReceiveCallback(IAsyncResult ar)
{
try
{
// Fetch a user-defined object that contains information
object[] obj = new object[2];
obj = (object[]) ar.AsyncState;
// Received byte array
byte[] buffer = (byte[]) obj[0];
// A Socket to handle remote host communication.
handler = (Socket) obj[1];
// Received message
string content = string.Empty;
// The number of bytes received.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
content += Encoding.Unicode.GetString(buffer, 0, bytesRead);
// If message contains "<Client Quit>", finish receiving
if (content.IndexOf("<Client Quit>") > -1)
{
// Convert byte array to string
string str = content.Substring(0, content.LastIndexOf("<Client Quit>"));
}
else
{
// Continues to asynchronously receive data
byte[] buffernew = new byte[1024];
obj[0] = buffernew;
obj[1] = handler;
handler.BeginReceive(buffernew, 0, buffernew.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), obj);
}
//this is used because the UI couldn't be accessed from an external Thread
BeginInvoke((ThreadStart)delegate()
{
tbAux.Text = content.Replace(@"<Client Quit>", "");
});
}
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
private void button_Send_Click(object sender, EventArgs e)
{
try
{
// Convert byte array to string
string str = textBox_Message2Client.Text + @"<Server Quit>";
// Prepare the reply message
byte[] byteData =Encoding.Unicode.GetBytes(str);
// Sends data asynchronously to a connected Socket
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
label_Message2Client.Text = "Message Sent by Server(" + (byteData.Length - 26).ToString() + "Byte)";
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
public void SendCallback(IAsyncResult ar)
{
try
{
// A Socket which has sent the data to remote host
Socket handler = (Socket)ar.AsyncState;
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
private void button_Disconnect_Click(object sender, EventArgs e)
{
try
{
if (sListener.Connected)
{
sListener.Shutdown(SocketShutdown.Both);
sListener.Close();
}
button_ServerStart.Enabled = true;
button_Send.Enabled = false;
button_Disconnect.Enabled = false;
label_Message2Client.Text = "Message to Client" ;
label_MessageReceived.Text = "Received Message";
textBox_MessageReceived.Text = string.Empty;
textBox_MessageReceived.Enabled = false;
textBox_Message2Client.Text = string.Empty;
textBox_Message2Client.Enabled = false;
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
}
}
客户代码为:
The client code is:
using System;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace TCP_Socket_Client
{
public partial class TCPSocketClient : Form
{
// Receiving byte array
byte[] bytes = new byte[1024];
Socket senderSock;
private TextBox tbAux = new TextBox();
public TCPSocketClient()
{
InitializeComponent();
tbAux.TextChanged += tbAux_SelectionChanged;
ipAddressControl_Server.Focus();
button_Send.Enabled = false;
button_Disconnect.Enabled = false;
textBox_Message2Send.Enabled = false;
textBox_MessageReceived.Enabled = false;
}
private void tbAux_SelectionChanged(object sender, EventArgs e)
{
BeginInvoke((ThreadStart)delegate()
{
textBox_MessageReceived.Text = tbAux.Text;
label_MessageReceived.Text = "Message from Server(" + (2 * tbAux.Text.Length).ToString() + "Byte)";
}
);
}
private void button_Connect2Server_Click(object sender, EventArgs e)
{
int servPort = (textBox_Port.Text.Length != 0) ? Int32.Parse(textBox_Port.Text) : 8821;
try
{
// Create one SocketPermission for socket access restrictions
SocketPermission permission = new SocketPermission(NetworkAccess.Connect, TransportType.Tcp, ipAddressControl_Server.Text, servPort);
// Ensures the code to have permission to access a Socket
permission.Demand();
// Gets first IP address associated with a localhost
IPAddress ipAddr = IPAddress.Parse(ipAddressControl_Server.Text);
// Creates a network endpoint
IPEndPoint ipEndPoint = new IPEndPoint(ipAddr, servPort);
// Create one Socket object to setup Tcp connection
senderSock = new Socket(ipAddr.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
senderSock.NoDelay = false; // Using the Nagle algorithm
// Establishes a connection to a remote host
senderSock.Connect(ipEndPoint);
label_ConnectionState.Text = "Already Connectted to" + senderSock.RemoteEndPoint;
label_ConnectionState.ForeColor = Color.Blue;
button_Connect2Server.Enabled = false;
button_Send.Enabled = true;
button_Disconnect.Enabled = true;
textBox_Message2Send.Enabled = true;
textBox_MessageReceived.Enabled = true;
new Thread(new ThreadStart(delegate{ReceiveDataFromServer();})).Start();
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
private void button_Send_Click(object sender, EventArgs e)
{
try
{
//<Client Quit> is the sign for end of data
string theMessageToSend = textBox_Message2Send.Text;
byte[] msg = Encoding.Unicode.GetBytes(theMessageToSend + @"<Client Quit>");
// Sends data to a connected Socket.
int bytesSend = senderSock.Send(msg) - 26; //"<Client Quit>" is 26Byte
label_Message2Server.Text = "Message to Server(" + bytesSend.ToString() + "Byte)";
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
private void ReceiveDataFromServer()
{
try
{
// Receives data from a bound Socket.
int bytesRec = senderSock.Receive(bytes);
// Converts byte array to string
String theMessageToReceive = Encoding.Unicode.GetString(bytes, 0, bytesRec);
// Continues to read the data till data isn't available
while (senderSock.Available > 0)
{
bytesRec = senderSock.Receive(bytes);
theMessageToReceive += Encoding.Unicode.GetString(bytes, 0, bytesRec);
}
tbAux.Text = theMessageToReceive.Replace(@"<Server Quit>", "");
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
private void button_Disconnect_Click(object sender, EventArgs e)
{
try
{
// Disables sends and receives on a Socket.
senderSock.Shutdown(SocketShutdown.Both);
//Closes the Socket connection and releases all resources
senderSock.Close();
button_Connect2Server.Enabled = true;
button_Send.Enabled = false;
button_Disconnect.Enabled = false;
label_ConnectionState.Text = "No Connection to Server";
label_ConnectionState.ForeColor = Color.Red;
textBox_Message2Send.Enabled = false;
textBox_Message2Send.Text = string.Empty;
textBox_MessageReceived.Enabled = false;
textBox_MessageReceived.Text = string.Empty;
label_Message2Server.Text = "Message to Server";
label_MessageReceived.Text = "Message from Server";
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());
}
}
}
}
现在,我有两个问题。一个是每次启动并从客户端发送第一条消息后,服务器会显示它,但如果发送了另一条消息,则服务器显示第一条消息而不是第二条消息。客户也是如此。另一种是当服务器关闭连接时,客户端仍然显示已连接的状态。感谢您的任何建议。
Now, I have two problems. One is that each time after it''s start and a first message was sent from the client, the server shows it, but if aniother message was sent then, the server shows the first not the second message. So does the client. The other is that when the server close the connection, the client still shows a connectted already state. Thanks for any suggestion。
推荐答案
这篇关于为什么Scoket只工作一次?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!