I have a server that accepts all sorts of commands, and I need to make it so that I can still send photos. I tried to do something like this: I first encoded the image and added <IMAGE> in the beginning, so that the server understood that this image and here all the problems went away, it just can't work. And you need to know the username who sent this image. How to achieve this?

PS the client is written not on C #, so for information.

UPDATE:

Server code:

 public static void ReadCallback(IAsyncResult ar) { String content, sData, _sData = String.Empty; byte[] bData = { }; MemoryStream ms = new MemoryStream(); BinaryFormatter bf = new BinaryFormatter(); // 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); if (bytesRead > 0) { state.sb.Append(Encoding.GetEncoding(866).GetString(state.buffer, 0, bData.Length)); content = state.sb.ToString(); Console.WriteLine(content); if (content.IndexOf("<FILE_SEND>") > -1) { memoryStream.Write(bData, 0, bData.Length); file_send = false; if (content.IndexOf("<FILESEND>") > -1) { Console.WriteLine("Good"); Stream fileStream = new FileStream(@"C:\output.jpg", FileMode.Create); memoryStream.Position = 0; fileStream.CopyTo(memoryStream); memoryStream.CopyTo(fileStream); fileStream.Close(); memoryStream.Close(); memoryStream = new MemoryStream(); Send(handler, content); } else { handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } else { // Not all data received. Get more. handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } }` 

Do not pay attention to how I decode the text, the code is simply cut there .. Well, the problem is not even in the encoding, but how to get this data correctly, so that in addition to sending photos, commands of this type user get USER_NAME , etc. work.

  • Show your server code, at least the relevant part. - VladD
  • Updated the question. - HackMemory
  • I think during the transfer of the image to the packages it is better to add a header with the uuid that the client generated. And this uuid is already tied to the client somewhere in the database. - Andrew Romanenko
  • Is there an example about uuid? About data serialization I know what it is, the question was different. - HackMemory

1 answer 1

I use for exchange with 1C exchange through data packing lines Using TCD to WM 6 as a wireless scanner to receive data from 1C

 using System.Collections.Generic; using System.Text; using System.IO.Compression; using System.IO; using System.Net.Sockets; namespace TCPConnectTo1C { public class ДляОбменаПоТСП { public static readonly Encoding CurrentEncoder=Encoding.GetEncoding(1251); public static byte[] РасжатьДанные(byte[] массивДанныхДляКоманды) { var memStream = new MemoryStream(массивДанныхДляКоманды); var DecompressStream = new MemoryStream(); using (GZipStream gzipStream = new GZipStream(memStream, CompressionMode.Decompress, false)) { Byte[] buffer = new Byte[1 << 16]; int h; while ((h = gzipStream.Read(buffer, 0, buffer.Length)) > 0) { DecompressStream.Write(buffer, 0, h); } } return DecompressStream.ToArray(); } public static byte[] СжатьДанные(byte[] Value) { var memStream = new MemoryStream(); memStream.Position = 0; using (GZipStream gzipStream = new GZipStream(memStream, CompressionMode.Compress)) { gzipStream.Write(Value, 0, Value.Length); gzipStream.Flush(); } return memStream.ToArray(); } private static byte[] МассивБайтовИзСтрима(NetworkStream стрим, int размерМассива) { byte[] result = new byte[размерМассива]; int количествоСчитанныхСимволов = 0; while (размерМассива > количествоСчитанныхСимволов) { количествоСчитанныхСимволов += стрим.Read(result, количествоСчитанныхСимволов, размерМассива - количествоСчитанныхСимволов); } return result; } public static void ЗаписатьМассивБайтовВСтрим(NetworkStream стрим, byte[] Массив) { стрим.Write(Массив, 0, Массив.Length); } public static bool ReadBool(NetworkStream стрим) { return BitConverter.ToBoolean(МассивБайтовИзСтрима(стрим,1), 0); } public static void Write(NetworkStream стрим, bool Value) { ЗаписатьМассивБайтовВСтрим(стрим, BitConverter.GetBytes(Value)); } public static Int32 ReadInt32(NetworkStream стрим) { return BitConverter.ToInt32(МассивБайтовИзСтрима(стрим,4), 0); } public static void Write(NetworkStream стрим, Int32 Value) { ЗаписатьМассивБайтовВСтрим(стрим, BitConverter.GetBytes(Value)); } public static string ReadString(NetworkStream стрим) { int РазмерДанных=ReadInt32(стрим); if (РазмерДанных == 0) return ""; var данные=МассивБайтовИзСтрима(стрим,РазмерДанных); return CurrentEncoder.GetString(данные, 0, данные.Length); } public static void Write(NetworkStream стрим, string Value) { if (Value.Length == 0) { Write(стрим, 0); return; } byte[] result = CurrentEncoder.GetBytes(Value); Write(стрим, result.Length); ЗаписатьМассивБайтовВСтрим(стрим,result); } public static string ReadCompressedString(NetworkStream стрим) { // int РазмерДанных = ReadInt32(стрим); // return CurrentEncoder.GetString(МассивБайтовИзСтрима(стрим, РазмерДанных)); bool ЭтоСжатаяСтрока = ReadBool(стрим); if (!ЭтоСжатаяСтрока) return ReadString(стрим); int РазмерДанныхДляКоманды = BitConverter.ToInt32(МассивБайтовИзСтрима(стрим, 4), 0); byte[] массивДанныхДляКоманды = МассивБайтовИзСтрима(стрим, РазмерДанныхДляКоманды); массивДанныхДляКоманды = РасжатьДанные(массивДанныхДляКоманды); return CurrentEncoder.GetString(массивДанныхДляКоманды, 0, массивДанныхДляКоманды.Length); } public static void WriteCompressedString(NetworkStream стрим, string Value) { if (Value.Length == 0) { Write(стрим, false); Write(стрим, 0); return; } byte[] result = CurrentEncoder.GetBytes(Value); var СжатыеДанные=СжатьДанные(result); if (result.Length>СжатыеДанные.Length) { Write(стрим, true); Write(стрим, СжатыеДанные.Length); ЗаписатьМассивБайтовВСтрим(стрим,СжатыеДанные); } else { Write(стрим, false); Write(стрим, result.Length); ЗаписатьМассивБайтовВСтрим(стрим,result); } } public static void ОтправтьКоманду(NetworkStream strim,string Команда, string ДанныеДляКоманды, bool ЕстьОтвет) { Write(strim,ЕстьОтвет); Write(strim,Команда); WriteCompressedString(strim,ДанныеДляКоманды); } public static void ПринятьКоманду(NetworkStream strim, out string Команда, out string ДанныеДляКоманды, out bool ЕстьОтвет) { ЕстьОтвет=ReadBool(strim); Команда=ReadString(strim); ДанныеДляКоманды=ReadCompressedString(strim); } } } 

And sending

 bool СоединитьсяССервером() { try { if (клиент == null) { клиент = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); клиент.Connect(ipEndpoint); } return true; } catch (SocketException ex) { MessageBox.Show("Ошибка соединения с сервером: " + ex.Message); клиент.Close(); клиент = null; return false; } } string ОтправтьКоманду(string Команда, string ДанныеДляКоманды, bool ЕстьОтвет, bool ЗакрытьСоединение, out bool ОшибкаСоединения) { var result = ""; ОшибкаСоединения = false; try { if (!СоединитьсяССервером()) { ОшибкаСоединения = true; return "Ошибка"; } using (var strim = new NetworkStream(клиент)) { try { ДляОбменаПоТСП.ОтправтьКоманду(strim, Команда, ДанныеДляКоманды, ЕстьОтвет); if (ЕстьОтвет) result = ДляОбменаПоТСП.ReadCompressedString(strim); } catch (SocketException ex) { MessageBox.Show("Ошибка отправки данных: " + ex.Message); result = "Ошибка"; ОшибкаСоединения = true; } if (ЗакрытьСоединение) { клиент.Close(); клиент = null; } } } catch (SocketException ex) { MessageBox.Show("Ошибка соединения с сервером: " + ex.Message); result = "Ошибка"; ОшибкаСоединения = true; } 

And on the server

 public void ОткрытьАйПиПортСНомеромПорта(int НомерПорта) { Event = new AutoResetEvent(false); ИдПотока = Thread.CurrentThread.ManagedThreadId; ЭтоЗакрытие = false; Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Any, НомерПорта); Server.Bind(ipEndpoint); Server.Listen(1); Server.BeginAccept(new AsyncCallback(ОбработкаСоединения), Server); } public void Ответить(string Ответ) { Otvet = Ответ; Event.Set(); } private void ОбработкаСоединения(IAsyncResult AsyncCall) { Socket listener = (Socket)AsyncCall.AsyncState; if (listener == null || (ЭтоЗакрытие)) return; Socket client = listener.EndAccept(AsyncCall); ВыполнитьКоманду(client); listener.BeginAccept(new AsyncCallback(ОбработкаСоединения), listener); } private void ВыполнитьКоманду(Socket client) { NetworkStream стрим=new NetworkStream(client); try { var Данные = ДляОбменаПоТСП.ПринятьКоманду(стрим); Event.Reset(); if (ПришлоСообщениеПоTCP!=null) ПришлоСообщениеПоTCP(Данные); if (Данные.ЕстьОтвет) { Event.WaitOne(); ДляОбменаПоТСП.WriteCompressedString(стрим, Otvet); } } catch (Exception e) { ЗаписатьОшибку(DateTime.Now.ToString() + e.ToString()); } } 

The project can be found here https://yadi.sk/d/G1FvJW_Ytfc5X

  • Well, I used GZip like you, well, when I get already compressed data, and I try to release it, an exception pops up about some kind of magic symbols or something like that. I don't know what could be the reason - HackMemory
  • I have this code still working with WinCE - Serginio
  • Added a link to the project yadi.sk/d/G1FvJW_Ytfc5X - Serginio