Article View: borland.public.cppbuilder.internet.socket
Article #4699Re: Winsock - App Hangs after sending a few messages.
From: Remy Lebeau (TeamB)
Date: Tue, 04 Jan 2005 18:41
Date: Tue, 04 Jan 2005 18:41
239 lines
9121 bytes
9121 bytes
"Luke" <lukedog264@msn.com> wrote in message
news:41da69f3$1@newsgroups.borland.com...
> if one socket did not complete a send command before attempting
> a retrieval there would be problems.
That is not correct. A socket can be written to and read from at the exact
same time. It is what allows sockets to be multi-threaded, such as one
thread reading while another writes. Now, if you have multiple threads
readings or multiple thread writing, then you can run into problems if you
don't synch those properly.
> Through more reading I found that when you use WSAAsyncSelect you
> can setup WndProc to handle your windowns messages. That process I
> am unfamiliar with how to setup if I started with Borland's Scratch
Application
> (from the new prompt).
You provide an HWND and a message identifier to WSAAsyncSelect(). If you
have a TForm, you simply provide its Handle property as the HWND, and
override its WndProc() method to intercept the message identifier.
> LocalSocketIn.sin_addr.s_addr = ((struct in_addr
*)(Host.h_addr))->s_addr;
<snip>
> LocalSocketIn.sin_addr.s_addr = inet_addr("My IP Address"); //
removed the actuall IP address for the post
Why are you assigning the a_addr value twice? Your first one is irrelevant
since you are immediately overwritting it with a different value.
> connect(Client, (SOCKADDR *)&LocalSocketIn, sizeof(SOCKADDR_IN);
You are trying to connect before you started the server that it is
connecting to.
> while (listen(Server, MAXCONN) == SOCKET_ERROR);
Why are you looping like that?
> Client = accept(Server, (SOCKADDR *)&LocalSocketIn, &length);
You are overwritting your Client pointer. You won't be able to free the
original client socket that was returned from socket(). Accepted
connections on a server are their own separate socket endpoints. You need
to keep all of endpoints around, as you have to free all endpoints that you
allocate.
> WSAAsyncSelect(Client, hWnd, C_SOCKET_MSG, 0);
Where did you assign hWnd?
> if(send(Client, Message->Text.c_str(), Message->Text.Length(),
NULL) == SOCKET_ERROR)
<snip>
> if (recv(Client, temp, 100, NULL) == SOCKET_ERROR) HandleError();
That code will never work properly. Because you overwrote your Client
pointer, you are having the socket write data back to itself. You need to
change your code to use a separate pointer when calling accept(). Use this
code instead:
#define C_SERVER_MSG (WM_APP + 100)
#define C_CLIENT_MSG (WM_APP + 101)
SOCKET Client = INVALID_SOCKET;
SOCKET Server = INVALID_SOCKET;
TList *Clients = NULL;
__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
Clients = new TList;
WSADATA wsaData;
WSAStartup(0x101,&wsaData);
}
__fastcall TForm1::TForm1(TComponent *Owner)
: TForm(Owner)
{
StopClientButtonClick(NULL);
StopServerButtonClick(NULL);
WSACleanup();
delete Clients;
}
void __fastcall TForm1::WndProc(TMessage &Message)
{
switch( Message.Msg )
{
case C_SERVER_MSG:
{
SOCKET Socket = (SOCKET) Message.WParam;
int Event = WSAGETSELECTEVENT(Message.LParam);
int Error = WSAGETSELECTERROR(Message.LParam);
switch( Event )
{
case FD_ACCEPT:
{
SOCKET s = accept(Server, NULL, NULL);
if( s != INVALID_SOCKET )
Clients->Add(s);
break;
}
case FD_CLOSE:
{
Clients->Remove(Socket);
closesocket(Socket);
break;
}
}
break;
}
case C_CLIENT_MSG:
{
int Event = WSAGETSELECTEVENT(Message.LParam);
int Error = WSAGETSELECTERROR(Message.LParam);
switch( Event )
{
case FD_READ:
{
unsigned long count = 0;
if( ioctlsocket(Client, FIONREAD, &count) !=
SOCKET_ERROR )
{
AnsiString temp;
temp.SetLength(count);
count = recv(Socket, temp.c_str(), count, NULL);
if( count != SOCKET_ERROR )
{
if( count > 0 )
{
temp.SetLength(count);
Memo->Text = temp;
}
else
{
closesocket(Client);
Client = INVALID_SOCKET;
}
}
else
HandleError();
}
else
HandleError();
break;
}
case FD_CLOSE:
{
closesocket(Client);
Client = INVALID_SOCKET;
break;
}
}
break;
}
default:
TForm::WndProc(Message);
break;
}
}
void __fastcall TForm1::StartServerButtonClick(TObject *Sender)
{
Server = socket(AF_INET, SOCK_STREAM, 0);
if( Server != INVALID_SOCKET )
{
SOCKADDR_IN LocalSocketIn = {0};
LocalSocketIn.sin_family = AF_INET;
LocalSocketIn.sin_addr.s_addr = INADDR_ANY;
LocalSocketIn.sin_port = htons(55000);
if( bind(Server, (SOCKADDR *)&LocalSocketIn,
sizeof(SOCKADDR_IN)) != SOCKET_ERROR )
{
if( WSAAsyncSelect(Server, Handle, C_SERVER_MSG, FD_ACCEPT |
FD_CLOSE) != SOCKET_ERROR )
{
if( listen(Server, MAXCONN) != SOCKET_ERROR )
return;
}
}
closesocket(Server);
Server = INVALID_SOCKET;
}
}
void __fastcall TForm1::StopServerButtonClick(TObject *Sender)
{
if( Clients->Count > 0 )
{
for(int x = 0; x < Clients->Count; ++x)
closesocket((SOCKET)Clients->Items[x]);
Clients->Clear();
}
if( Server != INVALID_SOCKET )
{
closesocket(Server);
Server = INVALID_SOCKET;
}
}
void __fastcall TForm1::StartClientButtonClick(TObject *Sender)
{
Client = socket(AF_INET, SOCK_STREAM, 0);
if( Client != INVALID_SOCKET )
{
SOCKADDR_IN LocalSocketIn = {0};
LocalSocketIn.sin_family = AF_INET;
LocalSocketIn.sin_addr.s_addr = inet_addr("127.0.0.1");
LocalSocketIn.sin_port = htons(55000);
if( connect(Client, (SOCKADDR *)&LocalSocketIn,
sizeof(SOCKADDR_IN)) != SOCKET_ERROR )
{
if( WSAAsyncSelect(Client, Handle, C_CLIENT_MSG, FD_READ |
FD_CLOSE) != SOCKET_ERROR )
return;
}
closesocket(Client);
Client = INVALID_SOCKET;
}
}
void __fastcall TForm1::SendButtonClick(TObject *Sender)
{
AnsiString Msg = Message->Text;
for(int x = 0; x < Clients->Count; ++x)
{
SOCKET s = (SOCKET) Clients->Items[x];
if( send(s, Msg.c_str(), Msg.Length(), NULL) == SOCKET_ERROR )
HandleError();
}
}
Gambit
Technical Details
Message-ID:
<41dae2fa$1@newsgroups.borland.com>Path:
arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!proxad.net!gatel-ffm!gatel-ffm!194.25.134.126.MISMATCH!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mailReferences:
<41da69f3$1@newsgroups.borland.com>Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,a0eb9df8217c6d4f X-Google-Attributes: gid11508e,public X-Google-Language: ENGLISH,ASCII-7-bit From: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com> Newsgroups: borland.public.cppbuilder.internet.socket References: <41da69f3$1@newsgroups.borland.com> Subject: Re: Winsock - App Hangs after sending a few messages. Date: Tue, 4 Jan 2005 10:41:27 -0800 Lines: 241 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1409 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409 NNTP-Posting-Host: 68.69.17.41 Message-ID: <41dae2fa$1@newsgroups.borland.com> X-Trace: newsgroups.borland.com 1104863994 68.69.17.41 (4 Jan 2005 10:39:54 -0800) Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!proxad.net!gatel-ffm!gatel-ffm!194.25.134.126.MISMATCH!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail