我正在编写程序来解决没有服务器的餐饮哲学家问题。它应该通过消息传递来工作。我的应用程序应运行5次,然后相互连接并自行解决问题。我在每个应用程序中放置了服务器端和客户端,我给了他们一个端口号。这张图片将显示我在说什么:
https://www.photobox.co.uk/my/photo/full?photo_id=500223105218
我想要的只是在客户端和服务器端之间发送消息。
但是我通过套接字处理程序从服务器端异步发送消息时出错。(在下面提到)
我搜索过但找不到任何相似的代码,那么如何直接从服务器端向客户端发送消息?
而且,我的想法如何?是对的吗?或者是错的。
这是我的代码的一部分,效果很好:
String status = "Thinking";
Boolean right = false;
Boolean left = false;
// Receiving byte array
byte[] bytes = new byte[1024];
SocketPermission permission;
Socket sListener;
Socket sListener1;
Socket sListener2;
Socket sListener3;
Socket sListener4;
Socket handler1;
Socket handler2;
Socket handler3;
Socket handler4;
Socket handler5;
Socket senderSock;
Socket senderSock1;
Socket senderSock2;
Socket senderSock3;
Socket senderSock4;
public Form1()
{
InitializeComponent();
}
//start button
private void button1_Click(object sender, EventArgs e)
{
try
{
IPEndPoint ipEndPoint=null;
IPEndPoint ipEndPoint1=null;
IPEndPoint ipEndPoint2 = null;
IPEndPoint ipEndPoint3 = null;
IPEndPoint ipEndPoint4 = null;
// Creates one SocketPermission object for access restrictions
permission = new SocketPermission(
NetworkAccess.Accept, // Allowed to accept connections
TransportType.Tcp, // Defines transport types
"", // The IP addresses of local host
SocketPermission.AllPorts // Specifies all ports
);
// Listening Socket object
sListener = null;
sListener1 = null;
sListener2 = null;
sListener3 = null;
sListener4 = 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
if (Sport.Text == "1000")
{
ipEndPoint = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}else if (Sport.Text == "1001")
{
ipEndPoint1 = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}
else if (Sport.Text == "1002")
{
ipEndPoint2 = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}
else if (Sport.Text == "1003")
{
ipEndPoint3 = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}
else if (Sport.Text == "1004")
{
ipEndPoint4 = new IPEndPoint(ipAddr, Convert.ToInt32(Sport.Text));
}
// Associates a Socket with a local endpoint
if (Sport.Text == "1000")
{
// Create one Socket object to listen the incoming connection
sListener = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener.Bind(ipEndPoint);
sListener.Listen(10);
}else if(Sport.Text == "1001")
{
sListener1 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener1.Bind(ipEndPoint1);
sListener1.Listen(10);
}
else if (Sport.Text == "1002")
{
sListener2 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener2.Bind(ipEndPoint2);
sListener2.Listen(10);
}
else if (Sport.Text == "1003")
{
sListener3 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener3.Bind(ipEndPoint3);
sListener3.Listen(10);
}
else if (Sport.Text == "1004")
{
sListener4 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
sListener4.Bind(ipEndPoint4);
sListener4.Listen(10);
}
label3.Text = "Server started.";
statusLabel.Text = "READY";
button1.Enabled = false;
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
//connect button
private void button2_Click(object sender, EventArgs e)
{
try
{
IPEndPoint ipEndPoint = null;
IPEndPoint ipEndPoint1 = null;
IPEndPoint ipEndPoint2 = null;
IPEndPoint ipEndPoint3 = null;
IPEndPoint ipEndPoint4 = null;
// Create one SocketPermission for socket access restrictions
SocketPermission permission = new SocketPermission(
NetworkAccess.Connect, // Connection permission
TransportType.Tcp, // Defines transport types
"", // Gets the IP addresses
SocketPermission.AllPorts // All ports
);
// 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
if (Cport.Text == "1000")
{
ipEndPoint = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}else if (Cport.Text == "1001")
{
ipEndPoint1 = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}
else if (Cport.Text == "1002")
{
ipEndPoint2 = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}
else if (Cport.Text == "1003")
{
ipEndPoint3 = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}
else if (Cport.Text == "1004")
{
ipEndPoint4 = new IPEndPoint(ipAddr, Convert.ToInt32(Cport.Text));
}
if (Cport.Text == "1000")//A
{
// Create one Socket object to setup Tcp connection
senderSock = new Socket(
ipAddr.AddressFamily,// Specifies the addressing scheme
SocketType.Stream, // The type of socket
ProtocolType.Tcp // Specifies the protocols
);
senderSock.NoDelay = false; // Using the Nagle algorithm
// Establishes a connection to a remote host
senderSock.Connect(ipEndPoint);
statusLabel.Text = "Socket connected to " + senderSock.RemoteEndPoint.ToString();
}
else if (Cport.Text == "1001")//B
{
senderSock1 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
senderSock1.NoDelay = false;
senderSock1.Connect(ipEndPoint1);
statusLabel.Text = "Socket connected to " + senderSock1.RemoteEndPoint.ToString();
}
else if (Cport.Text == "1002")//C
{
senderSock2 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
senderSock2.NoDelay = false;
senderSock2.Connect(ipEndPoint2);
statusLabel.Text = "Socket connected to " + senderSock2.RemoteEndPoint.ToString();
}
else if (Cport.Text == "1003")//D
{
senderSock3 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
senderSock3.NoDelay = false;
senderSock3.Connect(ipEndPoint3);
statusLabel.Text = "Socket connected to " + senderSock3.RemoteEndPoint.ToString();
}
else if (Cport.Text == "1004")//E
{
senderSock4 = new Socket(
ipAddr.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp
);
senderSock4.NoDelay = false;
senderSock4.Connect(ipEndPoint4);
statusLabel.Text = "Socket connected to " + senderSock4.RemoteEndPoint.ToString();
}
button2.Enabled = false;
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
label3.Text = "wait...";
Thread.Sleep(4000);
send_st();
}
这是我的代码,我在“Send(handler1,status);”中遇到错误 错误是:“对象引用未设置为对象的实例”
//send status from clnt to server
public void sendCToS(String str)
{
try
{
// Sending message
//<Client Quit> is the sign for end of data
byte[] msg = Encoding.Unicode.GetBytes(str + "<Client Quit>");
// Sends data to a connected Socket.
//send status from client to server
int bytesSend = senderSock.Send(msg);//receiver server tasmim giri va response send mikone
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
//it send hungry status from both to both!
public void send_st()
{
// 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];
Random rnd = new Random();
int delay = rnd.Next(2000, 5000);
while (true)
{
//System.Threading.Thread.Sleep(2000);
statusLabel.Text = status;
statusLabel.ForeColor = System.Drawing.Color.Blue;
Thread.Sleep(delay);
if (Sport.Text == "1000")//A
{
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler1, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
else if (Sport.Text == "1001")//B
{
Thread.Sleep(2000);
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler2, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
else if (Sport.Text == "1002")//C
{
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler3, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
else if (Sport.Text == "1003")//D
{
Thread.Sleep(2000);
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler4, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
else if (Sport.Text == "1004")//E
{
Thread.Sleep(3000);
status = "hungry";
statusLabel.Text = "HUNGRY";
statusLabel.ForeColor = System.Drawing.Color.Red;
//send status from server to clint
Send(handler5, status);
//send status from clnt to server
sendCToS(status);
label3.Text = "status Sent to left and right";
}
}
}
//server side
// Thread signal.
public static ManualResetEvent allDone = new ManualResetEvent(false);
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;
StateObject state = new StateObject();
// Begins to asynchronously receive data
handler.BeginReceive(
buffer, // An array of type Byt for received data
0, // The zero-based position in the buffer
buffer.Length, // The number of bytes to receive
0,// Specifies send and receive behaviors
new AsyncCallback(ReceiveCallback),//An AsyncCallback delegate
state // Specifies infomation for receive operation
);
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
}
public void ReceiveCallback(IAsyncResult ar)
{
String response = "ok";
try
{
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
// Received message
string content = string.Empty;
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<Client Quit>") > -1)
{
// All the data has been read from the client
label3.Text = content;
}
else {
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0,StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
这是服务器端功能的其余部分:
//func for echo back to client
private void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), handler);
}
public void SendCallback(IAsyncResult ar)
{
try
{
// A Socket which has sent the data to remote host
Socket handler = (Socket)ar.AsyncState;
// The number of bytes sent to the Socket
int bytesSend = handler.EndSend(ar);
label3.Text = "Sent {0} bytes to Client" + bytesSend;
}
catch (Exception exc) { MessageBox.Show(exc.ToString()); }
答案 0 :(得分:0)
我相信问题在于这一行: senderSock.Send(MSG);
您从未实例化senderSock,您只声明了它。 试试这个:
senderSock= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
senderSock.Send(msg);