Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hello everyone,

 

I am attempting to make a client/server program using sockets, but the program hangs on the Socket.AcceptConnection() line until there is a connection made. I was searching around and found some code on how to do it, but it used neither the AcceptConnection using a listener nor the read.ReadString(). I was wondering if anyone knows of some good tutorials or has some commented socket code laying around. MSDN was a waste of time, since I am new to network programming. I want to have multiple clients connected to the server at one time, and be able to send information back and forth. Not looking for many clients, max will probably be 50, if that.

 

I was using the following code:

[CS]

private void wfc()

{

TcpListener listener;

try

{

while(true)

{

listener = new TcpListener(50000);

listener.Start();

connection = listener.AcceptSocket();

 

clsClient CC = new clsClient(connection, this.t1);

 

listener.Stop();

listener = null;

}

}

catch(Exception e)

{

t1.Text = e.ToString();

}

 

}

[/CS]

 

 

Thanks,

-Cold

-Sean
Posted

public void Asynchronous_wfc()
{
//make a tcp socket
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//bind it to all nics on port 11000.
socket.Bind(new IPEndPoint(IPAddress.Any, 11000));
//listen for connections.
socket.Listen(5);
//method returns immediately but 'SomeoneConnected' will be invoked
//when someone connects.
socket.BeginAccept(new AsyncCallback(SomeoneConnected), socket);
}

private void SomeoneConnected(IAsyncResult result)
{
//result.AsyncState stores the 2nd argument of BeginAccept
//in this case, a socket, because I made it store a socket.
Socket socket = (Socket) result.AsyncState;

//you need to call end accept to get the connected socket.
Socket remoteEnd = socket.EndAccept(result);

//call begin accept again to get the next incoming connection.
socket.BeginAccept(new AsyncCallback(SomeoneConnected), socket);
}

What's so bad about delegates?

Posted
Thanks HJB, the way you explained it was, well, the best i've seen! I am starting to understand it now. So basically I am going to have to do the same thing for reading and writing data... I would have to make all of those using the same argument list so that they would be asynchronous...
-Sean
Posted

yes, there's more to know about asynchronous operations in the bcl. but that's the basic. There's stuff like the waithandle.

 

e.x.:

IAsynchResult result = socket.BeginAccept(new AsyncCallback(SomeoneConnected), socket);
//the 'WaitOne' will not return until a connection attempt is receievd.
result.AsyncWaitHandle.WaitOne();

Posted

Still confuzzled

 

Ok Hjb, I attempted for two days now to get the receive and send to work, no such luck (I must be brain dead).

 

In the server portion I have this:

[CS]

private void SomeoneConnected(IAsyncResult result)

{

//result.AsyncState stores the 2nd argument of BeginAccept

//in this case, a socket, because I made it store a socket.

Socket socket = (Socket) result.AsyncState;

 

//you need to call end accept to get the connected socket.

Socket remoteEnd = socket.EndAccept(result);

t1.Text += "\r\nSomeone Connected!";

//call begin accept again to get the next incoming connection.

 

byte[] buffer = System.Text.Encoding.UTF8.GetBytes("");

socket.BeginReceive(buffer,0,buffer.Length,System.Net.Sockets.SocketFlags.None,new AsyncCallback(CheckPackets),socket);

socket.BeginAccept(new AsyncCallback(SomeoneConnected), socket);

 

}

private void CheckPackets(IAsyncResult result)

{

byte[] buffer = System.Text.Encoding.UTF8.GetBytes("");

Socket socket = (Socket) result.AsyncState;

int dsocket = socket.EndReceive(result);

socket.Receive(buffer);

t1.Text+="\r\n" + System.Text.Encoding.UTF8.GetString(buffer);

socket.BeginReceive(buffer,0,buffer.Length,System.Net.Sockets.SocketFlags.None, new AsyncCallback(CheckPackets),socket);

}

[/CS]

 

In the client part I have:

[CS]

private void Connected(IAsyncResult result)

{

//result.AsyncState stores the 2nd argument of BeginAccept

//in this case, a socket, because I made it store a socket.

Socket socket = (Socket) result.AsyncState;

 

//you need to call end accept to get the connected socket.

socket.EndConnect(result);

label1.Text += "\r\nWe Connected!";

byte[] msg = System.Text.Encoding.UTF8.GetBytes("Test message!");

int i = socket.Send(msg);

Console.WriteLine("Sent " + i + " bytes of data.");

}

[/CS]

 

The client responds as sending 13 bytes of data, but in the server program I receive the error:

An unhandled exception of type 'System.InvalidOperationException' occurred in system.dll

 

Additional information: AcceptCallback

 

What am I doing wrong?!

-Sean
Posted

'remoteEnd' is what is connected to the "remote end", not 'socket'.

 

private void SomeoneConnected(IAsyncResult result)
	{
		//result.AsyncState stores the 2nd argument of BeginAccept
		//in this case, a socket, because I made it store a socket.
		Socket socket = (Socket) result.AsyncState;

		//you need to call end accept to get the connected socket.
		Socket remoteEnd = socket.EndAccept(result);
		t1.Text += "\r\nSomeone Connected!";
		//call begin accept again to get the next incoming connection.

		byte[] buffer = System.Text.Encoding.UTF8.GetBytes("");
		remoteEnd.BeginReceive(buffer,0,buffer.Length,System.Net.Sockets.SocketFlags.None,new AsyncCallback(CheckPackets),socket);
		socket.BeginAccept(new AsyncCallback(SomeoneConnected), socket);

	}

Posted
I think you need to post reproduceable code.

 

HJB, I do appreciate all the time and posts you made! ;)

 

Screenshot - Click Here

Server Code:

[CS]

private void SomeoneConnected(IAsyncResult result)

{

//result.AsyncState stores the 2nd argument of BeginAccept

//in this case, a socket, because I made it store a socket.

Socket socket = (Socket) result.AsyncState;

//you need to call end accept to get the connected socket.

Socket remoteEnd = socket.EndAccept(result);

t1.Text += "\r\nSomeone Connected!";

//call begin accept again to get the next incoming connection.

byte[] buffer = System.Text.Encoding.UTF8.GetBytes("");

remoteEnd.BeginReceive(buffer,0,buffer.Length,System.Net.Sockets.SocketFlags.None,new AsyncCallback(CheckPackets),remoteEnd);

socket.BeginAccept(new AsyncCallback(SomeoneConnected), socket);

}

private void CheckPackets(IAsyncResult result)

{

//byte[] buffer = System.Text.Encoding.UTF8.GetBytes("no");

Socket socket = (Socket) result.AsyncState;

int dsocket = socket.EndReceive(result);

if (dsocket<=0)

{

}

else

{

t1.Text+="\r\nReceived " + dsocket + " bytes of data." + " - " + System.Text.Encoding.UTF8.GetString(buffer);

}

socket.BeginReceive(buffer,0,buffer.Length,System.Net.Sockets.SocketFlags.None, new AsyncCallback(CheckPackets),socket);

}

[/CS]

 

Client code:

[CS]

/********************/

byte[] msg = System.Text.Encoding.UTF8.GetBytes("Test message!");

public Socket mysocket;

 

/********************/

private void Connected(IAsyncResult result)

{

//result.AsyncState stores the 2nd argument of BeginAccept

//in this case, a socket, because I made it store a socket.

Socket socket = (Socket) result.AsyncState;

//you need to call end accept to get the connected socket.

socket.EndConnect(result);

mysocket = socket;

label1.Text += "\r\nWe Connected!";

sendstuff(mysocket);

}

 

private void button2_Click(object sender, System.EventArgs e)

{

sendtuff(mysocket);

}

 

private void sendstuff(Socket socket)

{

socket.BeginSend(msg,0,msg.Length,System.Net.Sockets.SocketFlags.None,new AsyncCallback(sending),socket);

}

 

private void sending(IAsyncResult ar)

{

Socket socket = (Socket) ar.AsyncState;

int i = socket.EndSend(ar);

Console.WriteLine("Sent " + i + " Bytes.");

}

[/CS]

-Sean
Posted
private void SomeoneConnected(IAsyncResult result)
{
//result.AsyncState stores the 2nd argument of BeginAccept
//in this case, a socket, because I made it store a socket.
Socket socket = (Socket) result.AsyncState;
//you need to call end accept to get the connected socket.
Socket remoteEnd = socket.EndAccept(result);
t1.Text += "\r\nSomeone Connected!";
//call begin accept again to get the next incoming connection.
byte[] buffer = new byte[65536];
// instead of storing just the 'remote end'
// i'm going to store an array that contains the 'remote end' and
// the array the socket will write/store the received data.
remoteEnd.BeginReceive(buffer, 0, buffer.Length, System.Net.Sockets.SocketFlags.None, new AsyncCallback(CheckPackets), new object[] {remoteEnd, buffer});
socket.BeginAccept(new AsyncCallback(SomeoneConnected), socket);
}
private static void CheckPackets(IAsyncResult result)
{
int amtRecvd = socket.EndReceive(result);
// I access the data array to get the that was array
// created in SomeoneConnected(IAsyncResult).
object[] info = (object[]) result.AsyncState;
Socket remoteEnd = (Socket) info[0];
byte[] buffer = (byte[]) info[1];
if (amtRecvd == 0)
{
	//if amtRecvd == 0, all data has been receieved and the connection has been closed
	try
	{
		remoteEnd.Shutdown(SocketShutdown.Both);
	}
	finally
	{
		remoteEnd.Close();
	}
}
else
{
	t1.Text+="\r\nReceived " + amtRecvd + " bytes of data." + " - " + System.Text.Encoding.UTF8.GetString(buffer, 0, buffer.Length);
	byte[] buffer = new byte[65536];
	remoteEnd.BeginReceive(buffer, 0, buffer.Length, System.Net.Sockets.SocketFlags.None, new AsyncCallback(CheckPackets), new object[] {remoteEnd, buffer});
}
}

Posted
Ok, everything works now! Thanks for all you're help HJB, I appreciate it very much! The last question I have is, that when I run the server everythign is fine, then when a user connects it instantly jumps to 99% processor usage and slows my whole system down. Any idea why?
-Sean
Posted

I am so stupid.... I had the function sending blank messages. I didn't put the beginsend inside the braces! so whether or not information was there it sent itself in a constant never ending loop! wow, I think i've been staying up way too late... :p Thanks for everything again HJB, you're a huge asset to the community!

 

 

-THREAD RESOLVED-

-Sean

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...