服务器连接到多个客户端非常好,但服务器只发送第一行。我希望服务器读取文件并逐行发送到客户端,然后在下一个按钮单击服务器后应发送下一行给客户。有人可以帮忙吗? 客户代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Client
{
public partial class Form1 : Form
{
// State object for receiving data from remote device.
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
}
public delegate void TextManagerDelegate(string text);
TextManagerDelegate TextHandler;
private const int port = 15000;
static Socket client;
StateObject state;
// The response from the remote device.
private String response = String.Empty;
public Form1()
{
InitializeComponent();
TextHandler = new TextManagerDelegate(TextManager);
}
private void TextManager(string text)
{
textBox1.AppendText(text + Environment.NewLine);
}
private void StartClient()
{
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// bei Lust und Laune die deprecated warning fixen
IPAddress ipAddress = Dns.Resolve("localhost").AddressList[0];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
}
private void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
BeginInvoke(TextHandler, ("Socket connected to " + client.RemoteEndPoint.ToString()));
// Create the state object.
state = new StateObject();
state.workSocket = client;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
// Complete the connection.
client.EndConnect(ar);
// Reine demo-message - kann natürlich entfernt werden
//Send("Blub");
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
// in data sind die neuen daten
string data = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
BeginInvoke(TextHandler, ("Received data: " + data));
// prinzipiell sollte man auch hier beachten, ob der buffer für die datenmenge ausreicht etc.
// (selbes Spiel wie beim EmpfangsCallback im Server)
// der im stringbuilder sind sämtliche Daten aktuell konkateniert (weil es bereits im Bsp vorhanden war)
// man kann den aber auch rauswerfen
state.sb.Append(data);
response = state.sb.ToString();
}
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
}
private void Send(String data)
{
string text = MessageBox.Text;
text = 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.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), client);
}
private void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
BeginInvoke(TextHandler, ("Sent " + bytesSent + " bytes to server."));
// Signal that all bytes have been sent.
}
catch (Exception e)
{
System.Windows.Forms.MessageBox.Show(e.Message);
}
}
private void Connect_Click(object sender, EventArgs e)
{
StartClient();
}
private void Disconnect_Click(object sender, EventArgs e)
{
try
{
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception)
{
System.Windows.Forms.MessageBox.Show("Die Verbindung wurde abgebrochen");
}
}
private void SendMessage_Click(object sender, EventArgs e)
{
Send(MessageBox.Text);
}
}
}
服务器的代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Runtime.CompilerServices;
using System.IO;
namespace RanServer
{
public partial class Form1 : Form
{
public delegate void TextManagerDelegate(string text);
public ManualResetEvent allDone = new ManualResetEvent(false);
public List<StateObject> list = new List<StateObject>();
public Socket listener;
TextManagerDelegate TextHandler;
private const int port = 15000;
public Form1()
{
InitializeComponent();
TextHandler = new TextManagerDelegate(TextManager);
StartListening();
}
public void StartListening()
{
// Data buffer for incoming data.
byte[] bytes = new Byte[1024];
// Establish the local endpoint for the socket.
IPAddress ipAddress = Dns.Resolve("localhost").AddressList[0];
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
// Create a TCP/IP socket.
listener = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
try
{
ShowText.AppendText("\nServer is connected " + localEndPoint + Environment.NewLine);
listener.Bind(localEndPoint);
listener.Listen(100);
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
ShowText.AppendText("Waiting for a connections...");
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
// AcceptCallback wird aufgerufen, wenn ein neuer Client sich verbinden möchte
public void AcceptCallback(IAsyncResult ar)
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
list.Add(state);
BeginInvoke(TextHandler, "\nNew connection established.");
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
// ReadCallback wird aufgerufen, wenn der Client Daten an den Server geschickt hat
public void ReadCallback(IAsyncResult ar)
{
String content = String.Empty;
// 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.
try
{
int bytesRead = handler.EndReceive(ar);
BeginInvoke(TextHandler, ("\nVerbindung zum Client überprüfen!"));
if (bytesRead > 0)
{
string data = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
BeginInvoke(TextHandler, ("Received " + bytesRead + " bytes from socket: " + data));
// Der Stringbuilder im StateObjekt (state.sb) wurde vorgesehen falls der buffer nicht ausreicht, um alle Bytes
// auf einmal zu erhalten. Dann werden die Daten zerstückelt und auf mehrere Messages aufgeteilt.
// Der Stringbuilder baut diese wieder in einen String zusammen.
// There might be more data, so store the data received so far.
state.sb.Append(data);
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
//BeginInvoke(TextHandler, ("Total read " + content.Length + " bytes from socket. \n Data : " + content));
// Für Testzwecke kann man die empfangenen Daten an den Client zurückschicken
//Send(handler, content);
}
}
catch (Exception)
{
MessageBox.Show("Verbindung zum Client " + RuntimeHelpers.GetHashCode(handler) + " wurde abgebrochen");
}
}
// SendCallback wird aufgerufen, wenn der Server Daten an den Client verschickt hat
private void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
//BeginInvoke(TextHandler,("Sent " + bytesSent + " bytes to client(" + RuntimeHelpers.GetHashCode(handler)+ ")."));
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
//Stoppt die Verbindung und schließt das Programm wenn der Stop-Button geklickt wird.
private void StopButton_Click_1(object sender, EventArgs e)
{
//Iteriere durch Stateobject-Liste und schließe die einzelnen Sockets
foreach (StateObject state in list)
{
// Löse die verbindung auf
state.workSocket.Shutdown(SocketShutdown.Both);
state.workSocket.Close();
list.Remove(state);
}
listener.Close();
}
private void Send(Socket handler, String data)
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
BeginInvoke(TextHandler, ("Send data to: " + RuntimeHelpers.GetHashCode(handler)));
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
}
// Diese Funktion wird vom Button aufgerufen
public void SendFilesButton_Click(object sender, EventArgs e)
{
// Iteriere durch Stateobject-Liste und schicke an jedem die entsprechenden Daten
try
{
foreach (StateObject state in list)
{
string line;
StreamReader reader = new StreamReader("C:\\Users\\Chudnofsky\\Desktop\\Projekt\\Neu\\MesswerteAnlage.txt");
line = reader.ReadLine();
//string data = "foo";
// den string mit dem Inhalt der jeweiligen nächsten Zeile befüllen
// die letzte ZeilenNr ist in state.zeilenVerschickt drinnen
Send(state.workSocket, line);
state.zeilenVerschickt++;
}
}
catch (Exception)
{
MessageBox.Show("Es besteht keine Verbindung zum Client!!!");
}
}
public void TextManager(string txt)
{
ShowText.AppendText(Environment.NewLine + txt);
}
}
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 1024;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
// mitzählen der Anzahl der verschickten Zeilen
public int zeilenVerschickt = 0;
}
}
答案 0 :(得分:1)
StreamReader reader = new StreamReader("C:\\Users\\Chudnofsky\\Desktop\\Projekt\\Neu\\MesswerteAnlage.txt");