I have a TCPListener in C# and the client in Unix C. I use TcpClient.Client.SendFile for transmitting a file to client socket in Unix and it works fine for plain txt file. It fails to produce the full file on the unix end, when I send JPEG files. Any Idea?
C# code part
============
static void Main(string[] args)
{
TcpListener serverSocket = new TcpListener(10001);
TcpClient clientSocket = default(TcpClient);
serverSocket.Start();
Console.WriteLine(" >> Server Started");
clientSocket = serverSocket.AcceptTcpClient();
Console.WriteLine(" >> Accept connection from client");
while ((true))
{
try
{
NetworkStream networkStream = clientSocket.GetStream();
byte[] bytesFrom = new byte[10025];
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom).TrimEnd('\0');
Console.WriteLine(" >> Data from client - " + dataFromClient +" Length "+ dataFromClient.Length);
string a1 = "C:\\MRTD\\PICTURE\\abc.jpg";
clientSocket.Client.SendFile(a1);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
}
}
}
}
Unix C code to read the file
============================
char *tcp_recv( int id_type )
{
register int nbytes;
static char readbuf[MAXLINE];
static char tempbuf[980000];
int ngot = 0, bulk_data=0, p_read_val;
char * x, * y, * z, *j, *k, *x1, *bar;
char bulk_buf[180000], tempstr1[180000] , fstr[40], termtor[40];
int fd_ready;
fd_set read_fds; /* Read file descriptors */
int fd_port = gfd_sock;
struct timeval timeout;
timeout.tv_sec = 3600;
timeout.tv_usec = 0;
while (TRUE)
{
FD_ZERO( &read_fds );
FD_SET( fd_port, &read_fds );
strcpy(fstr,"FAIL");
if((fd_ready = select(fd_port+1,&read_fds,NULL,NULL,&timeout))< 0)
{
if( errno == EINTR ) { continue; }
logmsg("ERROR select() returned errno %d", errno );
logmsg("Select error waiting for packet." );
return fstr;
}
else if( fd_ready == 0 )
{
logmsg("Timeout waiting for packet.");
strcpy(fstr,"TIMEOUT");
return fstr;
}
memset( readbuf, 0x00, sizeof( readbuf ));
memset( br_kde, 0x00, sizeof( br_kde ));
if((nbytes = read( fd_port, readbuf, sizeof(readbuf)-1 )) < 0 )
{
logmsg( "tcp_recv: nbytes %d, errno %d, %s", nbytes, errno, strerror( errno ) );
if (errno == EINTR || errno == EAGAIN )
{
errno = 0;
continue; /* assume SIGCLD */
}
else
{
/*
* connection failer.
*/
logcon( "Desko connection failed. Pier link is DOWN!" );
logmsg( "Desko connection failed. Pier link is DOWN!" );
close_files();
exit (1);
break;
} /* end else if */
}
else
{
logmsg("tcp_recv: readbuf is %s, bytes %d", readbuf, nbytes);
strcat(tempbuf, readbuf);
logmsg("tempbuf is %s", tempbuf );<== full file listing is missing in case of JPEG
}
return tempbuf;
}
}
Related
I am Sending 68bytes of data using UDP Protocol.
68bytes of data consist of 4byte of int and random 64byte of byte array. uint seq starts with zero and it will increase if client send datagram to server once at a time. I used BitConverter.GetBytes for data's seq to make byte array.
public class NewData
{
public uint seq;
public byte[] data = new byte[64];
public NewData()
{
seq = 0;
data = null;
}
public NewData(uint seq, byte[] data)
{
this.seq = seq;
this.data = data;
}
}
Server has 2 Threads. 1 Thread will Enqueue and the other thread will Dequeue. (Producer and Consumer Thread)
I tried to check the data is coming well.
private readonly ConcurrentQueue<NewData> queue = new ConcurrentQueue<NewData>();
private void ReceiveThread()
{
int recv;
uint seq = 0;
byte[] datagram = new byte[1024];
List<byte> list = new List<byte>(); // for enqueue seq test
while (true)
{
autoresetevent.WaitOne();
if (Dispatcher.Invoke(() => (string)StartButton.Content == "Stop"))
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(endpoint);
socket.Blocking = false;
IPEndPoint sender = new IPEndPoint(IPAddress.Any, Dispatcher.Invoke(() => Convert.ToInt32(portTextBox.Text)));
EndPoint tmpRemote = (EndPoint)sender;
while (true)
{
try
{
recv = socket.ReceiveFrom(datagram, ref tmpRemote);
}
catch (SocketException e)
{
Thread.Sleep(threadSleep);
continue;
}
////------------------------------------------------------------------------
//// To Test Datagram Sequence
////------------------------------------------------------------------------
//for (int i = 0; i < 4; i++)
//{
// list.Add(datagram[i]);
//}
//Debug.Write(Convert.ToString(BitConverter.ToUInt32(list.ToArray(), 0)) + " ");
//list.Clear();
NewData newdata = new NewData(seq, datagram);
queue.Enqueue(newdata);
////------------------------------------------------------------------------
//// To check queue Count. if, queue Count = Client packet sent, no packet lost
////------------------------------------------------------------------------
//Debug.Write(Convert.ToString(queue.Count()) + " ");
seq++;
if (Dispatcher.Invoke(() => (string)StartButton.Content == "Start"))
{
socket.Close();
break;
}
Thread.Sleep(threadSleep);
}
}
}
}
private void FileSaveThread()
{
uint packet_lost = 0;
uint oldValue = 0;
uint currentValue = 0;
int j = 0; // for index
List<byte> sequenceList = new List<byte>(); // sequenceList
while (true)
{
autoresetevent2.WaitOne()
NewData newdata = new NewData();
if (queue.TryDequeue(out newdata))
{
for (j = 0; j < 4; j++)
sequenceList.Add(newdata.data[j]);
oldValue = BitConverter.ToUInt32(sequenceList.ToArray(), 0); // oldValue에 현재값 저장
queue.TryPeek(out newdata);
for (j = 0; j < 4; j++)
sequenceList.Add(newdata.data[j]);
currentValue = BitConverter.ToUInt32(sequenceList.ToArray(), 0); // oldValue에 현재값 저장
//Debug.Write(Convert.ToString(currentValue) + " ");
sequenceList.Clear();
if (!(currentValue == oldValue + 1))
{
packet_lost++;
Dispatcher.Invoke(() => dataResultTextBox.Text += " Packet_Lost : " + packet_lost + "\n");
}
}
Thread.Sleep(threadSleep);
}
}
The datagram's seq missing after 973.
Debug.Write () says
... 970 971 972 974 977 981 984 987 991 994 998 1001 1004 1007 1010 1014 1017 1021 1023 1027 1030 1034 1037 ...
Why does interval changed since the datagram sequence increased 1 at a time?
Or Should I think about other way to change byte array to Int?
Edit) I am sending data per 10ms. It works when i send data per 100ms.
client code
private async void DataSender(int num, int cycle, string ip, int port)
{
uint dataSequence = 0;
byte[] data = new byte[64]; // 64byte data
byte[] byteDataSeq = new byte[4]; // int sequence to byte
byte[] datagram = new byte[1024]; // seq + data
List<byte> datagramList = new List<byte>();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ip), port); // 서버의 주소 지정
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); // udp 소켓 client 선언
while (true)
{
if ((string)startButton.Content == "Start")
{
break;
}
random.NextBytes(data);
byteDataSeq = BitConverter.GetBytes(dataSequence);
datagramList.AddRange(byteDataSeq);
datagramList.AddRange(data);
datagram = datagramList.ToArray();
datagramList.Clear();
client.SendTo(datagram, ep);
dataSequence++;
await Task.Delay(cycle);
}
}
If Client sends data and sleep for 10ms,
Dequeue Thread should not sleep more than 10ms. It should be more faster than sender.
For example, If you send data per 5ms, transaction per second will be 200 data. Then your Dequeue Thread should not sleep. Even 1 ms sleep will cause error.
Debug.Write will cause error too. If you try to print every data that socket received, Dequeue thread won't work properly.
I've set up TCP client in C# and server in C.
When I want to transfer file, some packets are lost and file is not saved properly.
I've compared PDF file I tried to transfer and half of packets were not saved, so I couldn't open it on another computer.
client code:
public void SendFile(string file, string destPath = "C:\\")
{
int bufferSize = 1024;
byte[] filebuff = new byte[bufferSize];
string fileName = destPath + file;
//send to TcpServer request to send file
stream.Write(textToBytes("RECEIVEFILE"), 0, 11);
try
{
FileStream streamFile = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryReader binReader = new BinaryReader(streamFile);
//send file name to TcpServer
stream.Write(textToBytes(file), 0, file.Length);
//get file size
long filesize = streamFile.Length;
//send file size to TcpServer
//sendData(stream, BitConverter.GetBytes(filesize));
//if file doesn't exist
if (file == null)
{
Console.WriteLine("Error.");
}
//if file is empty
if (filesize == 0)
{
Console.WriteLine("File size: 0");
return;
}
int totalLength = Convert.ToInt32(filesize);
Console.WriteLine("Totallength: " + totalLength);
long numberOfPackets = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(streamFile.Length) / bufferSize));
int currentPacketLength;
for (int i = 0; i < numberOfPackets; i++)
{
if (filesize > bufferSize)
{
currentPacketLength = bufferSize;
totalLength = totalLength - currentPacketLength;
}
else
currentPacketLength = totalLength;
filebuff = new byte[currentPacketLength];
//streamFile.Read(filebuff, 0, currentPacketLength);
binReader.Read(filebuff, 0, currentPacketLength);
stream.Write(filebuff, 0, filebuff.Length);
}
streamFile.Close();
}
catch
{
Console.WriteLine("There's no file...");
}
}
public void DownloadFile(string fileName)
{
byte[] recBuffer = new byte[1024];
byte[] fileNameBytes;
long received = 0;
long receivedAll = 0;
byte[] fileData = new byte[1024];
stream.Write(textToBytes("SENDFILE"), 0, 8);
fileNameBytes = Encoding.UTF8.GetBytes(fileName);
stream.Write(fileNameBytes, 0, fileNameBytes.Length);
byte[] fileSizeBytes = new byte[4];
stream.Read(fileSizeBytes, 0, fileSizeBytes.Length);
int bytes = BitConverter.ToInt32(fileSizeBytes, 0);
Console.WriteLine("I'm downloading file...");
while (receivedAll < bytes)
{
received = stream.Read(fileData, 0, fileData.Length);
if (received < 0)
{
Console.WriteLine("Error");
break;
}
BinaryWriter bWrite = new BinaryWriter(File.Open("C:\\" + fileName, FileMode.Append));
bWrite.Write(fileData);
bWrite.Close();
receivedAll += received;
}
if(receivedAll == bytes)
{
Console.WriteLine("File downloaded successfuly.");
}
}
server code:
void ReceiveFile(int client_socket)
{
const int buffsize = 1024;
char buff[buffsize];
long filesize, received = 0, receivedall;
char filenamechar[512];
std::string filename, fullFilename;
memset(filenamechar, 0, 512);
/*
if(recv(client_socket, filenamechar, 512, 0) != 512)
{
printf("Error - filename.\n");
return;
}
fullFilename = "/Users/xxx/" + std::string(filenamechar);
*
if(recv(client_socket, &filesize, sizeof(long), 0) != sizeof(long))
{
printf("Child process: error.\n");
return;
}*/
filesize = 331776;
std::fstream fileFromClient;
fullFilename = "/Users/xxx/sockets.pdf";
fileFromClient.open(fullFilename, std::ios::binary | std::ios::out);
receivedall = 0;
while (receivedall < filesize)
{
memset(buff, 0, 1024);
received = recv(client_socket, buff, 1024, 0);
if(received <= 0)
{
std::cout << "error" << std::endl;
break;
}
receivedall += received;
fileFromClient << buff;
fputs(buff, stdout);
}
fileFromClient.close();
std::cout << "\nreceivedall: " << receivedall << std::endl;
std::cout << "filesize: " << filesize << std::endl;
if(receivedall != filesize)
printf("Error\n");
else
printf("File saved successfuly\n");
}
void SendFile(int client_socket)
{
char path[512];
char fileName[512];
char fullFileName[512];
long fileLen, sent, sentAll, read;
struct stat fileinfo;
FILE* file;
unsigned char bufor[1024];
memset(path, 0, 512);
strcpy(path, "/Users/xxxx/");
if (recv(client_socket, fileName, 512, 0) <= 0)
{
printf("Child process: error\n");
return;
}
strcpy(fullFileName, strcat(path, fileName));
printf("Child process: client wants file: %s\n", fullFileName);
if (stat(fullFileName, &fileinfo) < 0)
{
printf("Child process: can't get file info\n");
return;
}
if (fileinfo.st_size == 0)
{
printf("Child process: file size: 0\n");
return;
}
fileLen = fileinfo.st_size;
if (send(client_socket, &fileLen, sizeof(long), 0) != sizeof(long))
{
printf("Child process: error\n");
return;
}
sentAll = 0;
file = fopen(fullFileName, "rb");
if (file == NULL)
{
printf("Error\n");
return;
}
while (sentAll < fileLen)
{
read = fread(bufor, 1, 1024, file);
sent = send(client_socket, bufor, read, 0);
if (read != sent)
break;
sentAll += sent;
printf("Child process: sent %ld bytes\n", sentAll);
}
if (sentAll == fileLen)
printf("Child process: file sent successfuly\n");
else
printf("Child process: error\n");
fclose(file);
return;
}
How to guarantee that each packet will be saved properly?
One problem is with this line:
fileFromClient << buff;
This will write out the contents of buff until a zero byte is found. Since your are transferring a binary file, you can expect these bytes to be frequent. The rest of the received packet will not be written.
Rather than using the << operator, you should use
fileFromClient.write(buff, received);
I have a small program to receive UPD Packets. I have some bit problem in receiving packets . I actually need to revce packets by id for example "position (packet id: 196) , Location :187 etc" With my code i get some data but i dont know how to find the id and how to get real data inside the packet.
Packet Header
|SYNC Byte|SYNC Byte|Data Length|Identifier|Data Bytes|Checkssum|
|1(0x24) |2(0x40) |Byte |Bye | |Byete |
Field :Sync Bytes SIZE: 2 Bytes
Field :Data Length SIZE: 1 Byte
Field :Packet Identifier SIZE: 1 byte
Field :Data SIZE: 0-255 bytes
Field :Checksum SIZE: 1 byte
enter code here
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.IO;
namespace SimpleUdpReciever
{
class pProgram
{
static void Main(string[] args)
{
int localPort = 18006;
IPEndPoint remoteSender = new IPEndPoint(IPAddress.Any, 0);
bool flag = false;
for (int i = 0; i < args.Length; i++)
{
string cmd = args[i];
string value;
int tempInt;
IPAddress tempAddress;
switch (cmd)
{
case "-lp":
value = GetValue(args, ref i);
if (int.TryParse(value, out tempInt))
localPort = tempInt;
break;
case "-rp":
value = GetValue(args, ref i);
if (int.TryParse(value, out tempInt))
remoteSender.Port = tempInt;
break;
case "-rh":
value = GetValue(args, ref i);
if (IPAddress.TryParse(value, out tempAddress))
remoteSender.Address = tempAddress;
else if (int.TryParse(value, out tempInt) && tempInt == 0)
remoteSender.Address = IPAddress.Any;
break;
case "-?":
default:
PrintHelpText();
flag = true;
break;
}
}
// Exit application after help text is displayed
if (flag)
return;
// Create UDP client
UdpClient client = new UdpClient(localPort);
UdpState state = new UdpState(client, remoteSender);
// Start async receiving
client.BeginReceive(new AsyncCallback(DataReceived), state);
// Wait for any key to terminate application
Console.ReadKey();
client.Close();
}
private static void DataReceived(IAsyncResult ar)
{
UdpClient c = (UdpClient)((UdpState)ar.AsyncState).c;
IPEndPoint wantedIpEndPoint = (IPEndPoint)((UdpState)(ar.AsyncState)).e;
IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receiveBytes = c.EndReceive(ar, ref receivedIpEndPoint);
bool isRightHost = (wantedIpEndPoint.Address.Equals(receivedIpEndPoint.Address)) || wantedIpEndPoint.Address.Equals(IPAddress.Any);
bool isRightPort = (wantedIpEndPoint.Port == receivedIpEndPoint.Port) || wantedIpEndPoint.Port == 0;
if (isRightHost && isRightPort)
{ string test5 = Encoding.ASCII.GetString(receiveBytes);
Console.WriteLine("test5 = {0}", test5);
}
// Restart listening for udp data packages
c.BeginReceive(new AsyncCallback(DataReceived), ar.AsyncState);
}
private static string GetValue(string[] args, ref int i)
{
string value = String.Empty;
if (args.Length >= i + 2)
{
i++;
value = args[i];
}
return value;
}
private static void PrintHelpText()
{
Console.WriteLine("Simple Udp Receiver is an application that prints incoming data to screen.");
Console.WriteLine("Data is converted to ASCII before printing.");[![enter image description here][1]][1]
Console.WriteLine("Command switches:");
Console.WriteLine("-? : Displays this text.");
Console.WriteLine("-lp : Set local receiving port. \"-lp 4001\" Default: 11000");
Console.WriteLine("-rp : Set remote sender port. \"-rp 4001\" Default: 0 (Any port)");
Console.WriteLine("-rh : Set remote sender ip. \"-rh 192.168.1.10\" Default: 0 (Any ip)");
Console.WriteLine("\n Example of usage:\nSimpleUdpReciver.exe -lp 11000 -rh 192.168.10.10 -rp 4001");
}
}
}
Out put Looks like this whiole running this program : $# za� �X
�� �
I'm developing a windows store application, using C#. I would like to make TCP connection to receive images (for now) from a desktop server. the server is in C++ .
I have a client C++ to test the function and it is working perfectly. Now what i want is a similar client but in C# . I tried converting it but no luck, i tried to use the same logic but i had tons of errors and deleted everything.
Help is appreciated,thanks.
C++ Server
int size = 8192; //image size
char* bufferCMP;
bufferCMP = (char*)malloc(sizeof(char)* size);
FILE *p_file;
p_file = fopen("C:\\Program Files\\img1.png", "rb");
fread(bufferCMP, 1, size, p_file);
fclose(p_file);
int chunkcount = size / DEFAULT_BUFLEN;
int lastchunksize = size - (chunkcount * DEFAULT_BUFLEN);
int fileoffset = 0;
printf("Sending actual Chunk");
while (chunkcount > 0)
{
iResult = send(ClientSocket, bufferCMP + (fileoffset * DEFAULT_BUFLEN), DEFAULT_BUFLEN, 0);
fileoffset++;
chunkcount--;
if (iResult != DEFAULT_BUFLEN)
{
printf("Sending Buffer size <> Default buffer length ::: %d\n");
}
else
{
printf("Sending Buffer size = %d \n", iResult, fileoffset);
}
}
printf("Sending last Chunk", lastchunksize);
iResult = send(ClientSocket, bufferCMP + (fileoffset * DEFAULT_BUFLEN), lastchunksize, 0);
`
C++ Client (to be converted into C#)
int size = 8192;
int FileCounter = 0;
bool flg = true;
char * fileComplete;
char * filesizeBuffer;
FILE *temp;
int receiveBuffer = 0;
int desiredRecBuffer = size;
//int desiredRecBuffer = DEFAULT_BUFLEN ;
fileComplete = (char*)malloc(sizeof(char)* size);
while (desiredRecBuffer > 0)
{
iResult = recv(ConnectSocket, fileComplete + receiveBuffer, desiredRecBuffer, 0);
//iResult = recv( ClientSocket, fileComplete + receiveBuffer , fileSize , 0 );
if (iResult < 1)
{
printf("Reveive Buffer Error %d \n", WSAGetLastError());
}
else
{
receiveBuffer += iResult;
desiredRecBuffer = size - receiveBuffer;
printf("Reveived Data size : %d \n", desiredRecBuffer);
}
}
FILE *File = fopen("C:\\Users\\amirk_000\\Pictures\\img1b.png", "wb");
fwrite(fileComplete, 1, size, File);
//flg = true;
free(fileComplete);
fclose(File);
Full example of C# client socket is available at MSDN
Modify the given SocketSendReceive method to write the received buffer (bytesReceived array) to a file stream.
Something like the following should do it:
using (var file = File.OpenWrite("myimage.png"))
{
do
{
bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);
file.Write(bytesReceived, 0, bytes);
}
while (bytes > 0);
}
So i decided to start learning it by giving myself some interesting task.
As a web developer i wanted to have my very own WebSocket server.
So i've written it but it only accepts the first request. After that there is Arithmetic operation onverflow.
Here is some code for you to see what am i doing wrong :S I'm really out of ideas.
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using WebSocket.Utils;
namespace WebSocket
{
class SocketReader
{
public EndPoint ipAddr { get; set; }
private Socket userSocket;
private byte[] buffer;
private string SOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
public SocketReader(Socket socket)
{
userSocket = socket;
ipAddr = socket.RemoteEndPoint;
Read();
}
private void Read()
{
//Read packet size
buffer = new byte[2];
userSocket.BeginReceive(buffer, 0, 2, SocketFlags.None, ReadCallbackStatic, null);
}
private void ReadCallbackStatic(IAsyncResult ar)
{
try
{
if (userSocket.EndReceive(ar) >= 1)
{
int bufferSize = BitConverter.ToInt16(buffer, 0);
buffer = new byte[bufferSize - 2];
//Read Packet
userSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReadCallback, null);
}
}
catch (Exception se)
{
Console.WriteLine("Something blew on ReadCallbackStatic");
Console.WriteLine(se.Message);
Console.WriteLine(se.StackTrace);
Disconnect();
}
}
private void ReadCallback(IAsyncResult ar)
{
try
{
//Copy the buffer so we can receive the next packet ASAP
byte[] buff = new byte[buffer.Length];
Array.Copy(buffer, buff, buffer.Length);
Read();
string handshakeStr = System.Text.Encoding.UTF8.GetString(buff);
string[] list = Regex.Split(handshakeStr, "\r\n");
//Sec-WebSocket-Key: S5o6fCVLRMJhdXTF3H9w3Q==
//Sec-WebSocket-Version: 8
string key = "";
string clientProtocol = "0";
foreach (string str in list)
{
if (String.IsNullOrEmpty(str)) { continue; }
if (str.Length > 20 && str.Substring(0, 19) == "Sec-WebSocket-Key: ")
{
key = str.Substring(19);
continue;
}
if (str.Length > 20 && str.Substring(0, 23) == "Sec-WebSocket-Version: ")
{
clientProtocol = str.Substring(23);
continue;
}
}
if (String.IsNullOrEmpty(key))
{
Disconnect();
}
SHA1 shaEnc = new SHA1CryptoServiceProvider();
byte[] byteString = ASCIIEncoding.ASCII.GetBytes(key + SOCKET_GUID);
byte[] hash = shaEnc.ComputeHash(byteString, 0, byteString.Length);
string acceptKey = Convert.ToBase64String(hash);
List<string> headers = new List<string>();
headers.Add("HTTP/1.1 101 Switching Protocols");
headers.Add("Upgrade: websocket");
headers.Add("Connection: Upgrade");
headers.Add("Sec-WebSocket-Accept: " + acceptKey);
foreach (string header in headers)
{
SendString(header + "\r\n");
}
Console.WriteLine(acceptKey);
SendString("\r\n");
}
catch (SocketException se)
{
Console.WriteLine("Something blew on ReadCallback");
Console.WriteLine(se.Message);
Disconnect();
}
}
private void SendString(string str)
{
userSocket.Send(Encoding.UTF8.GetBytes(str));
}
private void Disconnect()
{
userSocket.Disconnect(false);
Console.WriteLine("Client with ip {0} Disconnected", ipAddr);
}
}
}
It's shortened version of my class but the problem that is bugging me appears in "ReadCallbackStatic" on this line:
buffer = new byte[bufferSize - 2];
i really don't know what am i doing wrong :S.
The thing is that ... i actually handshake properly but then when i sent some information from the client to my server this exception is thrown
I did some debugging and it appears that somehow the buffer variable becomes negative number O.O
My guess would be that you're blowing up when the MSB is set, i.e. maybe the client is sending a number >= 32768 and < 65536, which (via your ToInt16) is becoming a large negative 16-bit number (or, alternatively, throwing an arithmetic overflow issue). I would try using ToUInt16 instead.
To be honest, you really don't need BitConverter here; depending on the endianness this is either:
int bufferSize = (buffer[0] << 8) | buffer[1];
or
int bufferSize = buffer[0] | (buffer[1] << 8);
I believe problem could be in case when buffer contains of zero numbers, so:
int bufferSize = BitConverter.ToInt16(buffer, 0); // 0
buffer = new byte[bufferSize - 2]; // 0 - 2 == -2
Which results in the overflow exception whilst executing new byte[-2]
I do not know the logic behind your code but I believe you should allocate a new buffer considering buffer.Length value