我正在嘗試使用C#創建遠程桌面服務器和客戶端。服務器捕獲屏幕,然後通過套接字發送給客戶端。我使用下面的代碼,但它只顯示客戶端上的jpeg圖像的一部分。我認爲這是因爲圖像是以多個數據包發送的,此時代碼只讀取一個數據包並顯示它。任何人都可以解釋我將如何更改我的代碼,以便在顯示它之前接收多個數據包(整個圖像)。通過C#套接字正確發送和接收?
Server代碼:
Socket serverSocket;
Socket clientSocket;
public Form1()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
serverSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 8221);
serverSocket.Bind(ipEndPoint);
serverSocket.Listen(4);
//Accept the incoming clients
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Stream Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Stop();
Rectangle bounds = new Rectangle(0, 0, 1280, 720);
Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
}
System.IO.MemoryStream stream = new System.IO.MemoryStream();
ImageCodecInfo myImageCodecInfo;
System.Drawing.Imaging.Encoder myEncoder;
EncoderParameter myEncoderParameter;
EncoderParameters myEncoderParameters;
myEncoderParameters = new EncoderParameters(1);
myImageCodecInfo = GetEncoderInfo("image/jpeg");
myEncoder = System.Drawing.Imaging.Encoder.Quality;
myEncoderParameter = new EncoderParameter(myEncoder, 40L);
myEncoderParameters.Param[0] = myEncoderParameter;
bitmap.Save(stream, myImageCodecInfo, myEncoderParameters);
byte[] imageBytes = stream.ToArray();
stream.Dispose();
clientSocket.Send(imageBytes);
timer1.Start();
}
正如你所看到的,我使用它具有間隔設置爲30,用於發送圖像的字節數的計時器。
客戶機代碼:
public Socket clientSocket;
byte[] byteData = new byte[2048];
MemoryStream ms;
public Form1()
{
InitializeComponent();
backgroundWorker1.RunWorkerAsync();
this.DoubleBuffered = true;
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
clientSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("MY EXTERNAL IP HERE"), 8221);
//Connect to the server
clientSocket.BeginConnect(ipEndPoint,
new AsyncCallback(OnConnect), null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SGSclient",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
private void OnConnect(IAsyncResult ar)
{
try
{
//Start listening to the data asynchronously
clientSocket.BeginReceive(byteData,
0,
byteData.Length,
SocketFlags.None,
new AsyncCallback(OnReceive),
null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Stream Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void OnReceive(IAsyncResult ar)
{
try
{
int byteCount = clientSocket.EndReceive(ar);
ms = new MemoryStream(byteData);
using (BinaryReader br = new BinaryReader(ms))
{
this.BackgroundImage = Image.FromStream(ms).GetThumbnailImage(this.ClientRectangle.Width, this.ClientRectangle.Height, null, IntPtr.Zero);
}
}
catch (ArgumentException e)
{
//MessageBox.Show(e.Message);
}
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), null);
}
客戶機是指爲接收所述圖像,然後在表格的背景顯示它。
您必須在圖像末尾設置一個分隔符,這些分隔符會影響圖像結束的服務器。它也被稱爲**文件結尾**(EOF)。 TCP不會將圖像分割爲適用於您的應用程序的邏輯數據包,因此您必須編寫自己的信息控制。 – 2012-08-03 18:57:37