Socket berichtje word aan elkaar geplakt?

Status
Niet open voor verdere reacties.

murdoch201

Gebruiker
Lid geworden
31 mei 2008
Berichten
336
Hoi,

Ik probeer nu een berichtje via winsock te sturen van mijn Windows Phone (C# .NET) naar een VB6 programma. Om de een of andere reden plakt hij afzonderlijke berichtjes aan elkaar vast tot 1 berichtje.

Code:
retVal = sl.Send("loginhost" + textBox1.Text);
            retVal = sl.Send("loginport" + textBox2.Text);
            retVal = sl.Send("logincit" + textBox3.Text);
            retVal = sl.Send("loginpriv" + passwordBox1.Password);
            retVal = sl.Send("loginworld" + textBox5.Text);
            retVal = sl.Send("loginbotname" + textBox6.Text);
            retVal = sl.Send("loginexecute");

En de class:

Code:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net.Sockets;
using System.Threading;
using System.Text;

namespace SocketLibrary
{
    public class SocketLibrary
    {
        Socket s = null;
        static ManualResetEvent done = new ManualResetEvent(false);

        public bool EstablishTCPConnection(string host, int port)
        {
            s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.RemoteEndPoint = new DnsEndPoint(host, port);
            socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object o, SocketAsyncEventArgs e)
            {
                done.Set();
            });
            done.Reset();
            s.ConnectAsync(socketEventArg);
            return done.WaitOne(10000);
        }

        public bool Send(string data)
        {
            if (s != null)
            {
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = s.RemoteEndPoint;
                socketEventArg.UserToken = null;

                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object o, SocketAsyncEventArgs e)
                {
                    done.Set();
                });

                socketEventArg.SetBuffer(Encoding.UTF8.GetBytes(data), 0, Encoding.UTF8.GetBytes(data).Length);
                done.Reset();
                s.SendAsync(socketEventArg);
                return done.WaitOne(10000);
                
            }
            return false;
        }

        public string Receive()
        {
            string received = "";
            if (s != null)
            {
                SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
                socketEventArg.RemoteEndPoint = s.RemoteEndPoint;

                socketEventArg.SetBuffer(new byte[1024], 0, 1024);
                socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object o, SocketAsyncEventArgs e)
                {
                    if (e.SocketError == SocketError.Success)
                    {
                        received = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred).Trim('\0');
                    }
                    done.Set();
                });


                done.Reset();
                s.ReceiveAsync(socketEventArg);
                done.WaitOne(10000);
            }
            return received;
        }
        public void CloseSocket()
        {
            if (s != null)
            {
                s.Close();
            }
        }
    }
}

Kan er iemand mij helpen?

Mvg,
murdoch201
 
Heeft het niet te maken met het feit dat je de recieve op 1024 bytes zet waardoor het lijkt alsof alles achter elkaar geplakt is ?
Verder is het volgensmij ook niet nodig dat de recieve asynchroon gaat toch. Ik heb een soortgelijk probleem gehad. Ik heb toendertijd simpelweg de client niet asynchroon gemaakt en geconnect met TCPClient. Hierdoor bleef de server nog wel asynchroon clients afhandelen.
 
Laatst bewerkt:
Ik heb zelf niet zoveel ervaring met sockets... Het gebruiken van de control gaat nog, maar deze library heb ik gewoon ergens gedownload... Is het mogelijk om hem aangepast te krijgen?

Mvg,
murdoch201
 
Ik zou zelf deze zelf splitten in een client en een server socket. De server socket kan je dan asynchroon maken en de client synchroon. Hoe ik het doendertijd opgelost heb (met behulp van een een tutorial):

server socket waar nog wat overbodige troep van het project in staat (kan er uitgefilterd worden natuurlijk)

[cpp]

public class ServerSocket
{
#region All data types used for this Object

private List<Socket> connectedClients = new List<Socket>();
private static bool disconnect = false;
private Socket socket;
private AsyncCallback workerCallBack;
private List<Logic> logicsList;
private List<Thread> logicThreadList;

#endregion

#region All functions used for this Object

/// <summary>
/// function Start, starts the server and opens for listening
/// </summary>
public void Start()
{
//init socket
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//create endpoint


//windows 7 is being a bitch about IPAddress.Pars("127.0.0.1")
//IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(HelperClass.LOCAL_HOST), HelperClass.PORT);
IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, HelperClass.PORT);

//bind endpoint to socket
socket.Bind(endPoint);

//listen
socket.Listen(10);

//create callback for user connect
socket.BeginAccept(new AsyncCallback(Connect),null);

Console.WriteLine("Server started.....");
Console.WriteLine("Awaiting clients...");
}


/// <summary>
/// function Connect, lets a socket connect
/// </summary>
/// <param name="async">IAsyncResult</param>
private void Connect(IAsyncResult async)
{
if (disconnect)
{
disconnect = false;
return;
}
try
{
Socket soc = socket.EndAccept(async);
connectedClients.Add(soc);
Console.WriteLine("Client connected...");
WaitForData(soc);
socket.BeginAccept(new AsyncCallback(Connect), null);
CreateLogicProcess( socket );
}
catch(Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}


/// <summary>
/// function WaitForData
/// </summary>
/// <param name="soc">Socket</param>
public void WaitForData(Socket soc)
{
try
{
if (workerCallBack == null)
{
workerCallBack = new AsyncCallback(OnDataRecieved);
}

//create a socket package
Package package = new Package();
package.socket = soc;

soc.BeginReceive(
package.buffer,
0,
package.buffer.Length,
SocketFlags.None,
workerCallBack,
package);
}
catch (Exception ex)
{
Console.WriteLine("Error " + ex.Message);
}
}


/// <summary>
/// function OnDataReceived ( triggers when data is being received on socket )
/// </summary>
/// <param name="async">IAsyncResult</param>
public void OnDataRecieved(IAsyncResult async)
{

Package package = async.AsyncState as Package;
Socket currentSocket = package.socket;

try
{
int sizeRecieved = currentSocket.EndReceive(async);
//Console.WriteLine("Recieved {0} bytes", sizeRecieved);
}
//no need to catch a specific exception
catch
{
Console.WriteLine("Connection error.. client will be removed");

int isNumber = connectedClients.IndexOf(currentSocket);

logicThreadList.RemoveAt(isNumber);
logicsList.RemoveAt(isNumber);

connectedClients.Remove(currentSocket);
currentSocket.Close();
currentSocket.Dispose();

return;
}

byte idByte = package.buffer[0];

int lenght = (int)package.buffer[1];//BitConverter.ToInt32(package.buffer, 1);

string[] parameters = Encoding.ASCII.GetString(package.buffer, 2, lenght).Split(',');
if (parameters.Length == 3)
{
switch (idByte)
{
//call SetSensor
case 0:

string trafficLightID = parameters[0];
string distance = parameters[1];
string direction = parameters[2];
SetSensor(trafficLightID, distance, direction, currentSocket);

break;
//not used
default:
Console.WriteLine("Invalid method call");
break;
}
}


//put in waiting state again.
WaitForData(currentSocket);
}


/// <summary>
/// function SetSensor
/// </summary>
/// <param name="trafficLightID">string</param>
/// <param name="distance">string</param>
/// <param name="currentSocket">socket</param>
private void SetSensor(string trafficLightID, string distance, string directionTo, Socket currentSocket)
{
try
{
logicsList.ToArray()[connectedClients.IndexOf(currentSocket)].SetSensor(trafficLightID, Convert.ToInt32(distance), directionTo );
}
catch (Exception e)
{
Console.WriteLine( e.StackTrace );
}
}


/// <summary>
/// function SendData
/// </summary>
/// <param name="dataToSend">byte[]</param>
public void SendData(byte[] dataToSend)
{
lock (this)
{
foreach (Socket s in connectedClients)
{
s.Send(dataToSend);
}
}
}


/// <summary>
/// function Dispose
/// </summary>
public void Dispose()
{
foreach (Socket s in connectedClients)
{
if (s.Connected)
{
s.Close();
}
s.Dispose();
}
disconnect = true;

if (socket.Connected)
{
try
{
socket.Close();
}
//no need to catch a specific exception
catch
{
Console.Write("Manual socket attempt to close socket");
}
}
socket.Dispose();
socket = null;
}


/// <summary>
/// function Connected
/// </summary>
/// <returns>boolean</returns>
public Boolean Connected()
{
return connectedClients.Count > 0;
}
}
[/cpp]

de SocketPacker:

[cpp]

using System.Net.Sockets;

namespace SocketProtocol
{
public class Package
{
public byte[] buffer = new byte[150];
public Socket socket;
}
}


[/cpp]



de client (waar ook nog wat overbodige troep in staat):

[cpp]

private TcpClient client = new TcpClient();
private Queue<byte[]> queue = new Queue<byte[]>();

public ClientSocket(string ip, GUI gui)
{
this.IPAdress = ip;
this.gui = gui;

}

public void Start()
{
try
{
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(IPAdress),HelperClass.PORT);
client.Connect(endPoint);

Console.WriteLine("Client connected...");

Thread reader = new Thread(new ThreadStart(Reader));
reader.IsBackground = true;
reader.Start();
Thread writer = new Thread(new ThreadStart(Writer));
writer.IsBackground = true;
writer.Start();

}
catch (Exception ex)
{
Console.WriteLine(string.Format("error in clientSocket.Start = {0}", ex.Message));
}
}

public void Reader()
{
try
{
BinaryReader streamReader = new BinaryReader(new BufferedStream(client.GetStream(), 150), ASCIIEncoding.ASCII);
while (true)
{
byte idByte = streamReader.ReadByte();
int length = (int)streamReader.ReadByte();
string[] parameters = new string(streamReader.ReadChars(length)).Split(',');

switch (idByte)
{
// call AddVehicle
case 0:
//init parameters
string type = parameters[0];
//parameter 1 = time
string location = parameters[1];
string direction = parameters[2];
System.Console.WriteLine("Command: " + idByte.ToString() + " type: " + parameters[0].ToString() + " location: " + parameters[1].ToString() + " direction: " + parameters[2]);

//gui.AddVehicle(type, location, direction);
addVehicleDelegate(type, location, direction);
break;

//call SetTrafficLight
case 1:
string id = parameters[0];
int state = Int32.Parse(parameters[1]);
//gui.SetTrafficLight(id, state);
setTrafficLightDelegate(id, state);
System.Console.WriteLine("Command: " + idByte.ToString() + " id: " + parameters[0].ToString() + " state: " + parameters[1].ToString());

break;
default:
Console.WriteLine("Invalid method call");
break;
}


}
}
catch
{
Console.WriteLine("Error");
}
}

public void Writer()
{
try
{
BinaryWriter streamWriter = new BinaryWriter(new BufferedStream(client.GetStream(), 150), ASCIIEncoding.ASCII);
while (true)
{
if (queue.Count > 0)
{
streamWriter.Write(queue.Dequeue());
streamWriter.Flush();
}
else
{
Thread.Yield();
}
}
}
catch
{
Console.WriteLine("Error");
}
}
}


[/cpp]

Hoop dat dit wat helpt :)
 
Helaas niet, de code ligt ver, ver weg van iets werkend... De eerste regel met <Socket> alleen al doet het niet, hij vraagt zich af wat die <> daar doen.
 
de imports moeten er nog wel in:

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using SocketProtocol;
using Controller.logic;
using System.Threading;
 
Code:
private TcpClient client = new TcpClient();

Nu heeft ie geen idee wat TCPClient is
 
Code:
Error	1	The type or namespace name 'TcpClient' could not be found (are you missing a using directive or an assembly reference?)	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	14	17	PhoneApp1
Error	2	The type or namespace name 'TcpClient' could not be found (are you missing a using directive or an assembly reference?)	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	14	40	PhoneApp1
Error	3	The type or namespace name 'NetworkStream' could not be found (are you missing a using directive or an assembly reference?)	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	15	17	PhoneApp1
Error	4	The name 'ASCIIEncoding' does not exist in the current context	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	49	43	PhoneApp1
 
Maak je een windows phone applicatie ? zo ja, dit is een uitgeklede versie van c# waarin een hoop libraries niet zitten en je dus deze error krijgt.
 
Bedankt, maar ehmm...

Code:
Error	1	'System.Net.Sockets.Socket' does not contain a definition for 'Connect' and no extension method 'Connect' accepting a first argument of type 'System.Net.Sockets.Socket' could be found (are you missing a using directive or an assembly reference?)	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	24	20	PhoneApp1
Error	2	'System.Net.Sockets.Socket' does not contain a definition for 'Receive' and no extension method 'Receive' accepting a first argument of type 'System.Net.Sockets.Socket' could be found (are you missing a using directive or an assembly reference?)	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	40	28	PhoneApp1
Error	3	The name 'ASCIIEncoding' does not exist in the current context	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	41	39	PhoneApp1
Error	4	'System.Net.Sockets.Socket' does not contain a definition for 'Send' and no extension method 'Send' accepting a first argument of type 'System.Net.Sockets.Socket' could be found (are you missing a using directive or an assembly reference?)	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	53	20	PhoneApp1
Error	5	The name 'ASCIIEncoding' does not exist in the current context	C:\Users\***\documents\visual studio 2010\Projects\PhoneApp1\PhoneApp1\ClientSocket.cs	53	25	PhoneApp1
 
hmkay O_o dan zou ik het ook niet weten. appart, zelfs windows mobile zou sockets moeten hebben lijkt mij
 
wat je zou kunnen doen is een Thread.Sleep(4); na elke Send doen, de data wordt tesnel verzonden zodat dat het lijkt alsof het in 1 pakket gegooit is. Dit is alleen niet echt een mooie oplossing voor je probleem. Er zijn vast betere oplossingen hiervoor te vinden.
 
Tjah... Het helpt nu wel ja, Thread.Sleep(800);... Maar nu zit ik alweer met een probleem.

Die berichtjes die hij hoort te ontvangen, krijgt ie maar 1 keer aan, en dan stopt ie met ontvangen. Enig idee hoe dat kan?
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan