Mark I went through and rearranged all my code to output the WSAGetLastError() msg so I could then look it up. I rebuilt two programs, just simple console programs in this manner, one acting as a server, other a client.
I sent a simple char array "Hello" and vuala it worked! The error codes were a great idea, I suppose in programming I should be more responsible and use those codes! I found out one of my sockets were not being built correctly, my client socket on the server side because of the error. Once I figured it out I fired up my server and sent a message with my client. Boom it showed up on the server end. I'm so happy it works! I can finally see how it all functions now. The server side waits after the connection has been accepted to receive data.
I was afraid I would have to drop recv() in some kind of infinite loop in order to catch incoming data but I guess not! It waits untill data is received or the connection is terminated before processing any code below it! Now that I got that outa the way I can fix the code in my windows based client/server and go from there!
Mark I hate to drag it on but I got to thinking. Why wouldnt TCP ensure a reliable delivery? I understand why UDP wouldnt but TCP has me a bit stumped. I just assumed it could be considered a reliable protocl.
It was my assumption that after TCP established a connection, through the method of acknowledgement replys from the receiver and the use of sequence numbers inherit to TCP that this wouldnt be a problem. I guess I got a little confused on this. Any clarification?
Also one final question! I have created a very basic wrapper class for my little console program but now I want to incorporate it into my chat GUI. I read somewhere that by turning one of the server's sockets to a WSAasyncsock or something of that nature that I could incorporate the recv into my windows message pump. The tutorial made it clear on how and where to setup my messags but was unclear as to which socket I need to make an windows based asyncronous socket, also won't the sender side have to send those windows messages as well? Otherwise at what point does my message pump just automatically know that data is coming in?
Did I make any sense there at all? =)
Mark your an excellent help! After this I promise I won't pester you any more!
TCP is indeed reliable. The thing is, it's a stream oriented protocol, so it
only understands bytes. You could send 32KB-sized "packets" but the
underlying protocol may split that however it needs to for delivery. TCP
guarantees you'll receive all the bytes sent, in order, but they won't necessarily
come in one recv() call. That's why you need to do whatever it takes so the send
and receive ends stay in sync. It's essentially a protocol on top of TCP.
For the UI, yes, an asynchronous socket is ideal. Event-driven socket communication
is very efficient.
On the server side, you use the socket returned by accept(). That's the socket
connected to the client.
On the client side, you already have the socket - the one you connected to the server with.
I recommend reading the docs for WSAAsyncSelect VERY carefully.
The easiest way to get started is to request notifications for FD_READ and FD_CLOSE.
Then your window will receive the message you specify whenever there's data to be "recv()"'d
from the socket, and when the connection is closed.
On any given FD_READ notification, you can read as many bytes as you need to. If all the bytes
you're expecting aren't there yet, you need to keep track of that for when you get the next FD_READ.
If more bytes than you recv() are available, you're guaranteed to get another notification.
Again....read the docs carefully
also won't the sender side have to send those windows messages as well?
No. Both ends of the connection handle everything themselves. Basically, just
sending and receiving bytes. The notifications are available so you don't have to
sit in a loop wasting CPU cycles waiting for data.
Once a connection is established, there's no difference between the client and the server ends.
You could actually use identical code on both ends.
Create Client Socket
WSAAsyncSelect(Client Socket) //Ive tried it here
Client SOcket = accept (Listening Socket)
//WSAAsyncSelect(Client Socket) //And I have tried it here.
If I try it higher up before I make the accept call, that place seems the most logical to me because it is the accept call that locks up the gui right? However when I do it the GUI locks up. If I telnet to my port, or use my little console program I made and connect to that port the GUI unfreezes and a connection is established as normal. If I try to send data nothing is received on my GUI end.
If I place the WSAAsyncSelect after the Accept command same thing. Client GUI hangs untill a connection is established. Once its established everything works however, I can even send text messages from my console program and it will output correctly on my GUI's interface.
I am guessing that I am assigning the correct socket into async mode and my windows messages are working and everything, but why would it still be locking up waiting for a connect? Perhaps I am missing something still!
I spent the last hour poken around MSDN libs and other sites and havnt been able to get a simple and descent example. Thanks again Mark, especially for your patience!
The listening socket is separate. Once it is placed in a listening state, that's
all it does. For that socket, you'd want to use the FD_ACCEPT flag to get a window message
when a client tries to connect.
The WSAAsyncSelect() calls can be made any time after the sockets are created.
Generally, it's done something like this....
For the listening socket, call WSAAsyncSelect(...FD_ACCEPT) after you call listen(), then
return to your GUI or whatever. When you get a message indicating FD_ACcept to your
window, THEN call accept().
For the client end of the connection, call WSAAsyncSelect(...FD_CONNECT) right after you
create the socket. Then set the socket to non-blocking mode using ioctlsocket(), something like:
Call connect() on the socket and return to the GUI - your window will receive the message when
connection is complete. When you receive the connect completion message, call
WSAAsyncSelect(...FD_READ|FD_CLOSE) on the socket to start receive and close notifications.
For the server end of the connection, when you receive an accept notification,
call accept() to create the connection socket. Set this socket to non-blocking mode using ioctlsocket() as shown above,
then call WSAAsyncSelect(...FD_READ|FD_CLOSE) to start receive and close
*EDIT* I crossed out the parts about setting the sockets to non-blocking.
Calling WSAAsyncSelct() does this for you
I am trying to display non-english text on the std console. I have tried various methods like
setconsole, _wsetconsole etc.. Defined _UNICODE and UNICODE macros also used wstring, wcout thinking that wide char variant might print the non-english text. Below is my sample program
using namespace std;
wstring nonEnglishName = _TEXT("槧雲鼻");
wcout << _TEXT("Name in japanese is = ") << nonEnglishName.c_str() << endl;
The output I am getting is = Name in japanese is = ₧▀ë_ò@
My system locate is still set to US_ENGLSH and I do not want to change it.
Can anybody please guide me regarding the correct procedure for displaying non-english text on the console?
-- modified at 13:46 Wednesday 12th September, 2007
I have a application that does some computations based on inputs from user, prints the results of the calcutaions in a file and exits. I am using ExitProcess() for exiting from the application. But while closing the application I get a error "The instruction at "0x73e6827a" referenced at "0x00157479c". The memory could not be read" .
When I use TerminateProcess() I dont get the error message eventhough TerminateProcess() is not a recommeneded method for exiting process. Why does this happen?
The difference b/w ExitProcess and TerminateProcess is ExitProcess will send DETACH message to all the loaded dll where TerminateProcess won't. So the error may occured on unloading some dll loaded by ur application.
Why can't you just move all of the COM instantiation and function calls into the thread?
Also if you are accessing/writing to a variable visible to more than one thread, you will need to protect that variable with a critical section or other thread synchronization object. In other words, if variable N is readable/writable to both threads A and B then you will need to protect this variable. A simple CriticalSection object should be sufficient.
It is 1800 here in Norway/Norwegen and I am leaving the office for the day, but there are many articles here on Codeproject which address the issues with regards to multithreading your application and synchronizing access to variables.