|
what a perfect way!
|
|
|
|
|
Thanks
> The problem with computers is that they do what you tell them to do and not what you want them to do. <
> If it doesn't matter, it's antimatter.<
|
|
|
|
|
sizeof operator is the right way. I cannot see the reason for avoiding it.
Veni, vidi, vici.
|
|
|
|
|
He thinks he can make the wheel rounder...
|
|
|
|
|
Hi,
I have a loop for which I am tryig to connect on four ports for which I only get two
connections I know sometimes sockets take a while to connect
the Creation of the Socket and connection take place in CWinThread Dervived ::Initinstance after the CAsyncSocket objects have been created
Server is a Dos "C" program on the same Windows Vista machine
below is the loop
I am connected thru a router that is kind of old don't know if thats the issue
or If an imporvment in my hardware might help
I put my derived CAsynSocket class inside a a CWinThread class hoping that if such
issues arise I might raise the priority of the thread
looking for any pointers from the experts out there
// loop in CWinApp::Initinstance
for (i = 0, start_port = 11007; i < 4; start_port++, i++)
{
threadptr[i] = new SockCLeintThread(start_port);
if (threadptr[i] == NULL)
m_pMainWnd->MessageBox("SockClientThreadFail",NULL,MB_ICONERROR);
threadptr[i]->CreateThread(CREATE_SUSPENDED,0,NULL);
threadptr[i]->flags.is_connected = 0;
threadptr[i]->ipaddr = "192.168.1.4";
SetThreadName(threadptr[i]->m_nThreadID,thread[i]);
threadptr[i]->ResumeThread();
}
// My Casynsocket .h file
lass SockClient : public CAsyncSocket
{
DECLARE_SERIAL(SockClient)
public:
SockClient(UINT myport);
SockClient();
~SockClient();
char *sockbuffer; int num_buff;
CWnd *send_wnd;
int thread_no;
UINT port;
private:
int busy; protected:
virtual void OnReceive(int nErrorCode);
virtual void OnSend(int nErrorCode);
virtual void OnConnect(int nErrorCode);
virtual void OnClose(int nErrorCode);
}
IMPLEMENT_SERIAL(SockClient,CAsyncSocket,VERSIONABLE_SCHEMA | 2)
SockClient::SockClient()
{
sockbuffer = new char[300];
}
SockClient::SockClient(UINT myport)
{
port = myport;
sockbuffer = new char[300];
}
SockClient::~SockClient()
{
}
void SockClient :: OnConnect(int nErrorcode)
{
if(nErrorcode == 0)
Sockevent.SetEvent();
UNREFERENCED_PARAMETER(nErrorcode);
CAsyncSocket::OnConnect(nErrorcode);
busy = 1;
AsyncSelect(FD_WRITE);
}
void SockClient::OnClose(int nErrorCode) {
SockCLeintThread* current = dynamic_cast<SockCLeintThread*>(current);
current = (SockCLeintThread*)AfxGetThread();
current->flags.is_connected = 0;
CAsyncSocket::OnClose(nErrorCode);
}
void SockClient :: OnSend(int nErrorcode)
{
int bytes_sent;
if (num_buff > 0)
{
bytes_sent = Send(sockbuffer,num_buff,0);
num_buff = num_buff - bytes_sent;
CAsyncSocket::OnSend(nErrorcode);
AsyncSelect(FD_READ);
}
}
void SockClient::OnReceive(int nErrorcode)
{
static int i=0;
i++;
int nRead;
nRead = Receive(sockbuffer, 4096);
switch (nRead)
{
case 0:
Close();
break;
case SOCKET_ERROR:
if (GetLastError() != WSAEWOULDBLOCK)
{
AfxMessageBox ("Error occurred");
Close();
}
break;
default:
num_buff = nRead;
}
CAsyncSocket::OnReceive(nErrorcode);
send_wnd->SendMessage(WM_RECEIVE_SOCK_MESS,0,(LPARAM)sockbuffer);
}
class SockCLeintThread : public CWinThread {
public:
DECLARE_DYNCREATE(SockCLeintThread)
public:
SockCLeintThread(UINT myport);
SockCLeintThread();
~SockCLeintThread();
CWnd *sendwindow;
CWnd *call_wnd;
char *thread_id;
SockClient thisocket;
void Sendit(WPARAM, LPARAM);
void Receiveit(WPARAM, LPARAM);
LPCTSTR ipaddr;
BOOL idle; allexceptions myallexception;
struct {
unsigned int is_connected : 1;
unsigned int busy : 1;
} flags;
protected:
virtual BOOL InitInstance(); DECLARE_MESSAGE_MAP()
};
IMPLEMENT_DYNCREATE(SockCLeintThread,CWinThread)
BEGIN_MESSAGE_MAP(SockCLeintThread, CWinThread)
ON_THREAD_MESSAGE(WM_SEND_SOCK_MESS,Sendit)
END_MESSAGE_MAP()
void SockCLeintThread::Sendit(WPARAM count, LPARAM command)
{
UNREFERENCED_PARAMETER(command);
thisocket.num_buff = count;
thisocket.AsyncSelect(FD_WRITE);
return;
}
void SockCLeintThread::Receiveit(WPARAM count, LPARAM command)
{
UNREFERENCED_PARAMETER(count);
UNREFERENCED_PARAMETER(command);
thisocket.num_buff = 0;
}
SockCLeintThread::SockCLeintThread()
{
m_bAutoDelete = FALSE;
}
SockCLeintThread::SockCLeintThread(UINT myport) : thisocket(myport)
{
m_bAutoDelete = FALSE;
}
SockCLeintThread::~SockCLeintThread()
{
}
BOOL SockCLeintThread::InitInstance()
{
int error_code;
MSG m_msgCur;
extern void SetThreadName( DWORD dwThreadID, LPCSTR szThreadName);
socklock.Lock();
if(thisocket.Create(thisocket.port,SOCK_STREAM,NULL)== 0)
{
error_code = GetLastError();
}
if (thisocket.AsyncSelect(FD_READ|FD_WRITE|FD_CONNECT|FD_CLOSE|FD_OOB|FD_ACCEPT) == 0)
error_code = GetLastError();
if( thisocket.Connect(ipaddr,thisocket.port) == 0)
{
error_code = GetLastError();
}
else
flags.is_connected = 1;
socklock.Unlock();
PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE);
return TRUE; }
|
|
|
|
|
Not sure what you're asking, this looks like a bit of a code dump. Typically connections won't take very long if you're within the same LAN, so you may have another issue with your code. By the way, if you're using an asynchronous socket, the connection is also asynchronous, meaning you don't sit there and wait for a response, the callback will be called when it's either connected or timed out.
ForNow wrote: PeekMessage(&m_msgCur, NULL, NULL, NULL, PM_NOREMOVE);
You don't have to manually create a message queue for a CWinThread.
|
|
|
|
|
You are right the CAsynSocket::OnConnect should be called by the framework one way or another at the very least with a WSAETIMEDOUT nErrorCode
I should put a TRACE in to printf the nerrorcode
|
|
|
|
|
Could you post some code?
|
|
|
|
|
I am recieving a buffer which is having unicode and ansi character. How can I read it so that I can get the actual string.
|
|
|
|
|
Please be a little bit more specific (e.g. by providing an example). Do you have a buffer that may contain an ANSI or Unicode (Microsoft wide character UTF16-LE, UTF16-BE, or UTF-8) string and you want to detect the encoding? If so, do you know the length of the buffer?
|
|
|
|
|
Yes you are right and I know the lenght of buffer.
|
|
|
|
|
Wide char strings stored in files usually begin with a BOM (Byte Order Mark)[^].
If there is no BOM in your case, use the ANSI strlen() function and compare the result with the buffer length without NULL bytes. If it matches, the string is ANSI or UTF-8. If not, it is probably a wide char string. For Microsoft Unicode (UTF-16LE), this can be verified by comparing the return value of wcslen() with the buffer length (multiply returned length by two / sizeof(wchar_t)).
This solution requires that the string in the buffer is NULL terminated. If not, create a new buffer with length + 2, copy the data and append two NULL bytes (two bytes to have a valid terminated wide char string).
If the strings in the buffer are NULL terminated, you may also look for two NULL bytes at the end of UTF-16 strings.
|
|
|
|
|
Thanks for your help but I dont know how to check BOM..can you show by example...
|
|
|
|
|
Detecting code page from BOM:
UINT nCP = 0; if (0 == memcmp(lpszBuf, "\xEF\xBB\xBF", 3))
nCP = CP_UTF8;
else if (0 == memcmp(lpszBuf, "\xFF\xFE", 2))
nCP = 1200; else if (0 == memcmp(lpszBuf, "\xFE\xFF", 2))
nCP = 1201;
However, this requires the presence of a BOM. With text files, there should be one for UTF-16 and may be one with UTF-8. If you get your data from elsewhere (e.g. as network package), there may be no BOM.
|
|
|
|
|
It will comapare the byte with 0xFFFE, 0xFEFF but my problem is to seperate out ANSI and UNICODE string from a BYTE buffer.
My buffer will will be like "ConnectInfo?ã„·ã„´??56.58.98.142?fgg?n?v HTT". In this buffer unicode data is "ã„·ã„´" and remaining data is in ANSI.
I need to seperate out the data and need to create a complete string of unicode characters.
|
|
|
|
|
That's why I asked for an example in my first post:
Your string seems to be UTF-8 encoded.
To decode it you can use MultiByteToWideChar() which converts it to a wide char string:
int nWideLen = ::MultiByteToWideChar(CP_UTF8, 0, lpszBuf, nLen, NULL, 0);
wchar_t *lpszWide = new wchar_t[nWideLen];
::MultiByteToWideChar(CP_UTF8, 0, lpszBuf, nLen, lpszWide, nWideLen);
delete [] lpszWide;
|
|
|
|
|
execuse me. where can I get some data about encoding. actualy, I don't know exactly what's the different between UTF8 and UNICODE. Thank you very much
|
|
|
|
|
Good starting points for such questions are Google and Wikipedia. For Unicode, they should both bring you to www.unicode.org.
Unicode is the standard and UTF-8 is one Unicode Transformation Format. Another encoding format is UTF-16LE which is used by Microsoft Windows (WCHAR and wchar_t types). When you read Unicode in Microsoft documentation, it refers mostly to the internally used UTF-16LE format.
|
|
|
|
|
thank you very much. what I really want to know is the details which may have some help for work. I will visit the site, thanks again.
|
|
|
|
|
We have a collection of items C(x)
A thread A is responsible for performing tasks for those items in a continous and circular way.
In coding terms, we would write :
void doWork()
{
while(true)
{
for each x in C(x)
perform task(x).
}
}
We have other threads, that write and remove items from C(x) :
void remove(x);
void Add(x);
Now comes the final specification :
The function task(x), returns either true or false. If false is returned, then it means, there no need to call task(x) for the same x
in the future, unless some thread makes a signal for us that the thread A should be processing all element x.
let's call this notification function :
void NotifyIncludeAllElements();
What is the best approach here ?
Push Framework - now released !
http://www.pushframework.com
|
|
|
|
|
x can be a structure variable -
struct _tagX
{
... Xdata;
...
bool process;
};
Now process can be used as a flag to decide if processing is needed.
|
|
|
|
|
The size of collection C(X) can be so much big, that we might be interested in isolate the elements that are temporarily ignored, in another collection.
Further more, if all items are ignored, i am hoping that thread A blocks and not consume CPU for nothing.
Finally, the rate of calls to NotifyIncludeAllElements can be so much high, that if we make a shared lock with thread A there, then the performance of processing of A is greatly affected.
I tried to think about semaphore, signals, CAS operations, but came up with particular solution, you ca see it in this class I called AbstractDistributor : (Link to CodePlex)
http://pushframework.codeplex.com/SourceControl/changeset/view/98598#1909758[^]
When I think about the problem I can see many real world scenarios applicable to it. I am wondering if it is already solved in a good way.
Push Framework - now released !
http://www.pushframework.com
|
|
|
|
|
I have follow code :
m_sHex.Format(_T("FFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFF"));
char* p = NULL;
const int nDec = strtol(m_sHex, &p, 16);
sUDec.Format(_T("%u"), nDec);
sDec.Format(_T("%d"), nDec);
and sUDec is '65535' and sDec is '65535' ... I expected to see sUDec 4.294.967.295 and sDec -1 ... what I'm missing ?
|
|
|
|
|
strtol() will stop parsing at the first character that is not a hex digit. In your string this is the first space character.
When you remove the spaces from your string, all will be parsed. However, this will produce an out of range error (errno is set to ERANGE and strtol() returns LONG_MAX ). Because your string represents a 4 x 4 x 8 = 128 bit number.
To handle unsigned numbers, you may also use strtoul() .
|
|
|
|
|
You are right ! Thank you !
|
|
|
|
|