Home » Community » Forums » » Programming with Asynchronous Sockets
  Intel sponsors gamedev.net search:   
[Control Panel] [Register] [Bookmarks] [Who's Online] [Active Topics] [Stats] [FAQ] [Search]

Add Forum to Favorites |  Send Topic To a Friend | View Forum FAQ | Track this topic

Page:   1 2 »»

 Last Thread Next Thread 
 Programming with Asynchronous Sockets
Post Reply 
[BEGIN TRANSMISSION]

Hello all you readers! I'm finally getting up to speed with this whole message board response thingy, just to let you know. Although I do enjoy all your adoring and supportive emails, I would appreciate it if simple questions and comments could be posted here so that future visitors may find answers and insights without having to clog up my inbox. Okay, so I really don't get THAT much fan mail, but hey - it'll be easier for everyone right? Besides that any ticks you have with my article can be discussed here, where all can add their input and I am saved a scathing back and forth email war between myself and the acussee. Course that hasn't happened yet but it's always good to be prepared. Yeeeaaah. So, if anyone ever happens to visit this desolate place, rest assured that starting today it is bookmarked and will be checked regularily by moi. Let the posting begin!

[END TRANSMISSION]

==============================
"Need more eeenput..."
- #5, "Short Circuit"
==============================

 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Nice article! I've never programmed winsock until I read Richard Hallett's "How to Create a Non-Blocking Server" and found your reply on his forum... I managed to get a little server/client chat proggie up in win32 using async sockets! Real nice!

You should maybe have a little about how you bind and listen on sockets as a server, now I had to take that from Hallett's tutorial. It wasn't really clear if you could just do the same in async as with blocking/non-nonblocking, but it worked out fine once you tried... anyway, great article!

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

I hate to brag, but this was my most popular article I ever wrote (out of seven) so it's no surprise you liked it The detractors are far and few between.

Anyways yeah, I like the way Richard's article fills in a few gaps mine left. The main thing to remember is that async sockets are really no different in theory than non-blocking sockets. As I point out in my article (in fact i dedicate a section to it) async is a Win32 process while non-blocking can be done in console apps. The theory behind them both is one and the same so their basic functions can be ported from one to the other easily.

Drew Sikora
A.K.A. Gaiiden

Blade Edge Software
Public Relations, Game Institute
Staff Member, GDNet

Read my online column! Now!!

 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Hey all,
First of all, i like that tutorial a lot. I have always wanted to make socket non-blocking, but now i am coding WinAPI, so i want to use Async sockets. But i really have no clue how to implement it in my code.

In what part of the WinAPI code do i have to place all the socket stuff? DO i have to bind() before the ASync.. and so on..

Can some one give me a hand here?
My email adress is tuppac@hotmail.com,

It would be nice....

 User Rating: 1015    Report this Post to a Moderator | Link

HEy there Anon Glad you enjoyed my article, it's helped a lot of people and I'm always glad when it helps more.

If you aren't programming a specific networking module, then you can place the code wherever suits you best. I like to create startup and shutdown functions where I create the socket and clean up afterwards. This works well for me. I start it all up before I enter the message pump. You should of course have message handlers in the um... message handler

As for the bind() isue, I this was brought to my attention just recently and I was surprised I never covered it because there's a very important thing that happens with bind() . If you bind a socket before declaring it async, then it automatically becomes blocking. This is fine if you still declare async later on, it's just some operations may not function the way you intended. It's better practice to bind the socket after you declare the socket async.

_________________________________________________________________

Drew Sikora
A.K.A. Gaiiden

ICQ #: 70449988
AOLIM: DarkPylat

Blade Edge Software
Staff Member, GDNet
Public Relations, Game Institute

3-time Contributing author, Game Design Methods , Charles River Media (coming GDC 2002)
Online column - Design Corner at Pixelate

NJ IGDA Chapter - NJ developers unite!! [Chapter Home | Chapter Forum]


 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Great tutorial. Searching a good article about Async stuff and found this great one. Thanks!

rgds
Christian

 User Rating: 1015    Report this Post to a Moderator | Link

I hate to admit it, but it's prob the only good one you'll find I remember searching for async stuff before I knew it - talk about impossible. Heck, WinSock tutorials alone were near impossible to come by... at least ones you could understand. I'm still getting thank-you emails about this one

 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Great article, thanks. In the FD_WRITE case, if my send() returns WSAEWOULDBLOCK, how do I know that the packet made it across? Breaking from the loop assumes all the data (at least in that packet) will make it over (since the 'data_sent' variable was incremented by the packet size BEFORE the send). Please advise. Thanks, again, my e-mail is abrumme@gte.net.

 User Rating: 1015    Report this Post to a Moderator | Link

You're right, my article didn't get into packet checking, because I felt just wrapping your head around the whole Async sockets deal was enough Besides, checking for packet integrity is more of a general topic anyways.

Generally you want to be in touch with the client to make sure all the data has received on the other side, otherwise you'll have to send the packet data again. I'm not to well-versed in this besides the basics, however. The technique is quite broad, I'm sure you'll find it discussed at length is a general networking article. Try the Articles and Resources section.

Glad you enjoyed the article.

 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link


This manual is wonderful, but i need it to program in Linux.
Anybody knows where can i get some info to work with asyn sockets under Linux...?

enforcer@navegalia.com

See u, Thanks...


 User Rating: 1015    Report this Post to a Moderator | Link

Oh man I wish you luck buddy. The reason I wrote this was out of frustration over lack of Win32 WinSock resources, I can't imagine trying to find something for Linux If i come across anything I'll be sure to send it your way. Got my eyes peeled...

 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Hi Drew !
Thanks very much for this really understandable explanation !

Really helped me a lot and saved my weekend from sleepless nights

Best Regards,
Stephan

 User Rating: 1015    Report this Post to a Moderator | Link

I was wondering when dos all those func's occur ??
do i say WinProc(FD_WRITE); or do start a send() function ??


 User Rating: 1015    Report this Post to a Moderator | Link

How do i decleare the buffer ???
and how do i make the FD_WRITE know that i want to well, use FD_WRITE ????

 User Rating: 1015    Report this Post to a Moderator | Link

When i try to connect to my Server program(blocking) with my client(Async), it gives me and Alredy in progress message. How do i correct this.

"Computers are only as smart as their programers"
My Site-> Still working on it.

 User Rating: 1242   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Just out of curiousity--why not use CAsyncSocket? Or are we already using it through the SOCKET macro? (Or did it not exist at the time of writing the article?)

Shaun

[edited by - stonstad on September 18, 2002 10:12:02 PM]

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

I don't think it existed at the time I wrote the article - I certainly hadn't heard about it back then. I still don't know about it - my work has taken me away from sockets since I wrote this

 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

quote:
Original post by Anonymous Poster

This manual is wonderful, but i need it to program in Linux.
Anybody knows where can i get some info to work with asyn sockets under Linux...?

enforcer@navegalia.com

See u, Thanks...



Search about using fork() under unix, you can make thread easily with it : one to wait, the other to process anything else...
So i searched example of using winsock and multi-threading, i think that may be better to manage blocking problems.

Cédric


 User Rating: 1015    Report this Post to a Moderator | Link

hi, i would like to start off by saying great tutorial, it has helped me learn a lot although i haven't been completly sucessful with it. i have read other tutorial and i have to admit that this one helped me out the most. any i have been tring to get my Asynchornous sockets working, which they do, but i don't recieve any messages other than FD_CONNECT so i really can't do anything with them. has anyone had this problem before or know possible reasons what i am doing wrong? i call WSAAsyncSelect() right after socket()

 User Rating: 1015   |  Rate This User  Send Private MessageView Profile Report this Post to a Moderator | Link

Glad you liked the article and it helped you. you won't get a lot of help from this thread though since it's mainly me who checks it... you should post this in the networking and multiplayer forum. In order to receive a message besides FD_CONNECT you have to send something from the client to the server. If you're doing this and it still doesn't work you may have set the sockets wrong or your send code could be wrong. I'll help as i can but I haven't touched sockets in like 2 years.

_________________________________________________________________

Drew Sikora
A.K.A. Gaiiden

ICQ #: 70449988
AOLIM: DarkPylat

Blade Edge Software
Staff Member, GDNet
Public Relations, Game Institute

3-time Contributing author, Game Design Methods , Charles River Media
Online column - Design Corner at Pixelate

Unnoficial IGDA chat! [polaris.starchat.net -> #igda]
NJ IGDA Chapter - NJ developers unite!! [Chapter Home | Chapter Forum]

"Real programmers don't work from 9 to 5. If any real programmers are around at 9am it's because they were up all night."
-Anon.

"It's not the size of the source that matters, it's how you use it"
- Self


 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

Hi, I do not like the way you send data to a socket with FD_WRITE.
you shouldn't send 1 byte at a time. the winsock default socket buffer size is 8192.
if I would use your method on a production server, it would be simply overkill. I mean... calling 8192 times the function is too much.
My application uses a 50 kb (51200 bytes) buffer. calling this function 51200 times for each client that is downloading from my server is unacceptable.
even though the send function is fast, this is where bottlenecks would appear in my application.

To fix this problem, the trick is to send BufferSize bytes. BufferSize is an unsigned integer that contains the size of the winsock buffer which is availabe with the getsockopt() function. you can use setsockopt() if you want to change its size.

however, the problem is that even though the default reported buffer is 8192 bytes, sending 8192 bytes won't cause a WSAEWOULDBLOCK. Not even sending 8193 bytes. I don't know how much the real buffer size is, but I can tell that its less than 8192 * 2 because when I send the data two times on the same socket it creates a WSAEWOULDBLOCK error and the excedent data is discarded (which means that if you're sending a file it won't be damaged because a packet is not sent 2 times).

Anyway, here is some sample code:
  
void FDWrite(SOCKET Sock, HANDLE HandleToFile) {
	//a static variable so that data is not allocated on each function call

	static TransferBuffer[SizeOfMySocketsBuffer];
	BOOL ReadFileRValue;
	DWORD NumBytesRead = 0;

	//read from the file or from your memory buffer. do whatever you like. I used this as an example

	if (!(ReadFileRValue = ReadFile(HandleToFile, TransferBuffer, SizeOfMySocketsBuffer, &NumBytesRead, NULL))) {
		EndTransfer(); //unable to read from file

		return;
	}

	//If the return value is nonzero and the number of bytes read is zero, the file pointer was beyond the 

	//current end of the file at the time of the read operation. 

	//transfer complete

	if (ReadFileRValue && NumBytesRead == 0) {
		EndTransfer(); //function to end your file transfer. call the shutdown() function, CloseFile() etc...

		return;
	}


	//this is the send loop, it will send the data then resend it to cause a WSAEWOULDBLOCK

	//in reality, this loop should be done only 2 times

	while(TRUE) {
		if (send(Sock, TransferBuffer, NumBytesRead, 0) == SOCKET_ERROR) { //send the whole read buffer

			if (WSAGetLastError() != WSAEWOULDBLOCK) {
				EndTransfer(); //socket error!!!

				return;
			}
			else {
				return; //we have filled the buffer, we will wait for another FD_WRITE...

			}
		}
		//we have read less than SizeOfMySocketsBuffer from our file, which means that either the file was smaller than

		//the buffer or we have finished reading it.

		if (NumBytesRead < SizeOfMySocketsBuffer) {
			EndTransfer();
			return;
		}
	}
}
  


 User Rating: 1015    Report this Post to a Moderator | Link

I won't claim to be a Master of Sockets so thx for the tip! I may have realized that error had I stuck with sockets longer... but my project was cut shortly after this article and I haven't touched sockets since. All readers take note.

 User Rating: 2077   |  Rate This User  Send Private MessageView ProfileView Journal Report this Post to a Moderator | Link

On the guy with the linux question just do non-blocking linux
client way easier all you do is a call to fcntl

 User Rating: 1015    Report this Post to a Moderator | Link

Drew Sikora said: "That’s right - read it and weep. Hope you weren’t planning on a nice simple console app there, bucko. This requires a nice spiffy Win32 app, and nothing less."

Does WSAEventSelect provide for asynchronous socket programming in a console app?

Regards,
Gareth


 User Rating: 1015    Report this Post to a Moderator | Link
Page:   1 2 »»
All times are ET (US)

Post Reply
 Last Thread Next Thread 
Forum Rules:
You may not post new threads
You may post replies
You may not edit your posts
You may not use HTML in your posts
Jump To:
Administrative Options: