TECHNOLOGIES
FORUMS
JOBS
BOOKS
EVENTS
INTERVIEWS
Live
MORE
LEARN
Training
CAREER
MEMBERS
VIDEOS
NEWS
BLOGS
Sign Up
Login
No unread comment.
View All Comments
No unread message.
View All Messages
No unread notification.
View All Notifications
Answers
Post
An Article
A Blog
A News
A Video
An EBook
An Interview Question
Ask Question
Forums
Monthly Leaders
Forum guidelines
Matthew Cox
NA
1
0
Asynchornous Sockets
Jan 10 2008 6:31 PM
Hey guys I'm having problems with some Asynchronous socketing that I have been trying. ...I don't want to post my entire code but I will try to put in what is necessary.
My problem is that I can't continue to send messages to my Server class and have them echo the message back to the Client more than ONE TIME.
I have gleaned some of my coding techniques through other examples so bear with my probable misinterpretation of their usage. :)
Here is the class that handles ANY data that is sent back to the Client:
public class Client
{
...
...
...
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
...
....
....
private void ListenForData()
{
while (true)
{
receiveDone.Reset();
ReceiveData(clientSocket);
receiveDone.WaitOne();
}
}
public void ReceiveData(Socket client)
{
try
{
StateObject stateObj = new StateObject();
stateObj.WorkSocket = client;
client.BeginReceive(stateObj.testBuff, SocketFlags.None,
new AsyncCallback(ReceiveDataCallback),
stateObj);
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
private void ReceiveDataCallback(IAsyncResult result)
{
StateObject stateObj = (StateObject)result.AsyncState;
Socket handler = (Socket)stateObj.WorkSocket;
int bytesRead = handler.EndReceive(result);
string data = String.Empty;
if (bytesRead > 0)
{
IList<ArraySegment<byte>> infoList = stateObj.testBuff;
//A user defined class that contains a method I write which seperates the data into its respective components of message and userID.
byte[][] temp = ConversionClass.generateByteArrays(infoList[0].Array);
byte[] msgBuff = temp[0];
byte[] clientBuff = temp[1];
string msg = Encoding.ASCII.GetString(msgBuff);
string Id = Encoding.ASCII.GetString(clientBuff);
string date = DateTime.Now.ToString();
data = date + ' ' + clientID + ": " + msg;
stateObj.StringBuffer.Append(data);
/*stateObj.StringBuffer.Append(Encoding.ASCII.GetString(
stateObj.Buffer, 0, bytesRead));*/
if (data.IndexOf(EOM) > -1)
{
data = data.Trim(EOM.ToCharArray());
notifyMessageHandlerUsers(data);
//ReceiveData(clientSocket);
//I tried just unblocking the receiveDone thread but it didn't work so i tried just recalling the receive method. That also does not work after the first message is received.
}
else
{
handler.BeginReceive(stateObj.testBuff, SocketFlags.None,
new AsyncCallback(ReceiveDataCallback),
stateObj);
}
}
//supposidly this would unblock the thread that is currently running the ListenForData() methed. But it appears to not be working.
receiveDone.Set();
}
....
....
....
}
just a few notes about this method. It is the callback method that is assigned when data is passed back thorugh the socket connection to the server. I chose to use an IList for the parameters rather than just a plain old buffer because I wanted to seperate the data ... date, clientID, message, etc... lol, but it just combines them all into one buffer anyways once they are received by the Server. So I use a 'End of Unit' (31) character to signify the seperation of data.
Example: (I know you can't just concatenate byte arrays like this but I'm in a hurry so bear with it ;) )
string message = "hello";
string id = "matt";
byte[] byteArray =
Encoding.ASCII.GetBytes(message)
+
31 + Encoding.ASCII.GetBytes(id);
As you can see, when actually done correctly ;) there would be signified diffences between the message and the id.
Now just for clarification, the ListenForData() method is called after a connection is made with the server and it gets through the loop to the call ReceiveData() and then the thread is blocked.
How do I get the thread to resume running after a message is finished transmitting?
thanks !
p.s
in case anyone decides to ask I'll just post my StateObject class as well: it's rough right now because I'm still in the learning process so I don't want to clean up code till I'm sure of what I'm doing.
public class StateObject
{
public const int BufferSize = 1024; // Size of receive buffer.
private Socket workSocket; // Client socket.
public IList<ArraySegment<byte>> testBuff;
private byte[] buffer; // Receive buffer.
private StringBuilder stringBuffer;//Received data String.
private string id; // Host or conversation ID
private string timeStamp;
public StateObject()
{
testBuff = new List<ArraySegment<byte>>(2);
byte[] msgBuff = new byte[BufferSize];
byte[] clientID = new byte[16];
testBuff.Add(new ArraySegment<byte>(msgBuff));
testBuff.Add(new ArraySegment<byte>(clientID));
buffer = new byte[BufferSize];
stringBuffer = new StringBuilder();
id = String.Empty;
timeStamp = DateTime.Now.ToString();
}
//nd all corresponding Properties for attributes
..
...
...
...
}
Reply
Answers (
0
)
code with a class and an array...Help!
Restarting an application once its closed