You Are Here:

Community: Developer Discussion Boards

#1 Old 有代码:在socket操作过程中,如何得到实际接收数据的长度? - 2003-05-15, 08:57

Join Date: Apr 2003
Posts: 47
ttkttkttk
Offline
Registered User
int CSocketTCPEngine::Receive(TDes8 &iRecvBuffer, TSockXfrLength& iLen)
{
// Receive data from the "server"
// m_iSocket.RecvOneOrMore(iRecvBuffer, 0, iStatus, iLen);
m_iSocket.Recv(iRecvBuffer, 0, iStatus, iLen);
// m_iSocket.Read(iRecvBuffer, iStatus );
// wait for connected
User::WaitForRequest(iStatus);
if (iStatus==KErrNone || iStatus==KErrEof)
return iRecvBuffer.Length();
else
return 0;
}

以上代码可以接受数据,但用了很多方法都没有得到实际接受到实际数据的大小,请问如何得到?
Reply With Quote

#2 Old 2003-05-15, 12:02

Join Date: Mar 2003
Posts: 3,175
Location: Beijing
Send a message via MSN to liuxg
liuxg's Avatar
liuxg
Offline
Forum Nokia Expert
Hi,

From your code, it seems nothing is wrong. I once did almost the same thing as you did. I got the length, and even I displayed in a control (I displayed strings).

Please make sure your sent data is also TBuf8 format (8-bit format) rather than in Unicode format. Could you please tell whether you got the length or not? or the length you got was not right? If it is the second case, how did you tell that the length was not right?

You can paste your code here. In this case, more people can see your code to help you!

Best regards,

Liuxg
Forum Nokia
Reply With Quote

#3 Old 2003-05-16, 03:36

Join Date: Apr 2003
Posts: 47
ttkttkttk
Offline
Registered User
我得到的实际接收的实际数据是正确的,但数据长度总是
零. 我把整个代码贴出来了:在代码中我用到了char*,
void*主要是为了代码的兼容性. 因为想把异步的socket操作
转化为同步socket操作,当每次发送一个请求时,会调用User::WaitForRequest(iStatus);等待请求完成后再返回。
希望各位高手施以援手。

// 头文件
#if !defined _SOCKETTCPENGINE_H_
#define _SOCKETTCPENGINE_H_

#include <e32std.h>
#include <e32base.h>
#include <es_sock.h>
#include <in_sock.h>

class CSocketTCPEngine : public CActive
{
public:
static CSocketTCPEngine* NewL();
~CSocketTCPEngine();
CSocketTCPEngine();
void ConstructL();

public:
virtual bool Connect(const TUint32 iAddress, const TUint iPort);
virtual int Send(const TDesC8 &iSendBuffer, TSockXfrLength& iLen);
virtual int Receive(TDes8 &iRecvBuffer, TSockXfrLength& iLen);
virtual void Close();

virtual bool Connect(const char *pcszHost, unsigned int iPort);
virtual int Send(const void *pBuffer, int cbBufSize);
virtual int Receive(void *pBuffer, int cbBufSize);

private: // From CActive
void RunL();
void DoCancel();

private:
/*! @var the socket server */
RSocketServ m_iSocketServ;

RSocket m_iSocket;

TSockXfrLength m_iSendLen;
TSockXfrLength m_iRecvLen;

/*! @var DNS name resolver */
RHostResolver m_iResolver;

/*! @var The result from the name resolver */
TNameEntry m_iNameEntry;

/*! @var The anme record found by the resolver */
TNameRecord m_iNameRecord;
};

#endif // _SOCKETTCPENGINE_H_

// 定义文件:

#include <in_sock.h>
#include <s32file.h>
#include <charconv.h>

#include "SocketTCPEngine.h"

///////////////////////////////////////////////
//
// Construct the engine
//
///////////////////////////////////////////////

CSocketTCPEngine* CSocketTCPEngine::NewL()
{
CSocketTCPEngine* self = new (ELeave) CSocketTCPEngine;
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(); // self
return self;
}

CSocketTCPEngine::CSocketTCPEngine()
:CActive(CActive::EPriorityStandard)
{
}

void CSocketTCPEngine::ConstructL()
{
CActiveScheduler::Add(this);

// Open channel to Socket Server
User::LeaveIfError(m_iSocketServ.Connect());

}

CSocketTCPEngine::~CSocketTCPEngine()
{
m_iSocketServ.Close();
Cancel();
}

void CSocketTCPEngine::RunL()
{

}

void CSocketTCPEngine:oCancel()
{

}

bool CSocketTCPEngine::Connect(const TUint32 iAddress, const TUint iPort)
{
TInt err;
// IP address specified here
TInetAddr localLoop(iAddress, iPort);

// Open a socket
err=m_iSocket.Open(m_iSocketServ, KAfInet, KSockStream, KUndefinedProtocol);
User::LeaveIfError(err);

// Make a connection
m_iSocket.Connect(localLoop, iStatus);

// wait for connected
User::WaitForRequest(iStatus);

if (iStatus==KErrNone)
return true;
else
return false;
}

void CSocketTCPEngine::Close()
{
m_iSocket.CancelAll();
// Close all sockets
m_iSocket.Close();
}

//int CSocketTCPEngine::Send(const void *pBuffer, int cbBufSize)
int CSocketTCPEngine::Send(const TDesC8 &iSendBuffer, TSockXfrLength& iLen)
{
// send some data to server
m_iSocket.Send(iSendBuffer, 0, iStatus, iLen);
// m_iSocket.Write(iSendBuffer, iStatus);

// wait for connected
User::WaitForRequest(iStatus);
if (iStatus==KErrNone)
return iSendBuffer.Length();
else
return 0;
}

//int CSocketTCPEngine::Receive(void *pBuffer, int cbBufSize)
int CSocketTCPEngine::Receive(TDes8 &iRecvBuffer, TSockXfrLength& iLen)
{
// Receive data from the "server"
// m_iSocket.RecvOneOrMore(iRecvBuffer, 0, iStatus, iLen);
m_iSocket.Recv(iRecvBuffer, 0, iStatus, iLen);
// m_iSocket.Read(iRecvBuffer, iStatus );

// wait for connected
User::WaitForRequest(iStatus);
if (iStatus==KErrNone || iStatus==KErrEof)
return iRecvBuffer.Length();
else
return 0;
}

bool CSocketTCPEngine::Connect(const char *pcszHost, unsigned int iPort)
{
TUint32 nAdressIP = 0;
TInetAddr addr;
TInt nRet = 0;

// change the char* to Unicode
RFs fsSession;
TInt fsret = fsSession.Connect(); // start a file session
if (fsret != KErrNone)
return false;

//follow to put another string to iInfoText2
CCnvCharacterSetConverter* converter = NULL;
converter = CCnvCharacterSetConverter::NewLC();

//Check if there is conversion between GBK/GB2312 and unicode
if(converter->PrepareToConvertToOrFromL(KCharacterSetIdentifierGb2312,
fsSession) != CCnvCharacterSetConverter::EAvailable)
User::Leave(KErrNotSupported);

TInt state=CCnvCharacterSetConverter::KStateDefault;

TPtrC8 source((TText8*)pcszHost);
HBufC* pIP=HBufC::NewL(source.Length());
TPtr16 ptr=pIP->Des();

//Leave if error in conversion.
if(CCnvCharacterSetConverter::EErrorIllFormedInput
== converter->ConvertToUnicode(ptr, source, state))
User::Leave(KErrArgument);

//clean for converter
CleanupStack::PopAndDestroy();

fsSession.Close(); // close the file session

nRet = addr.Input((const TDesC&)*pIP);
if(nRet == KErrNone)
{
nAdressIP = addr.Address();
}
else
{
// Initiate DNS
User::LeaveIfError(m_iResolver.Open(m_iSocketServ, KAfInet, KProtocolInetUdp));
// DNS request for name resolution
m_iResolver.GetByName(*pIP, m_iNameEntry, iStatus);

// wait for connected
User::WaitForRequest(iStatus);
if (iStatus!=KErrNone)
return false;

// connect
// DNS look up successful
m_iNameRecord = m_iNameEntry();

TBuf<15> ipAddr;
TInetAddr::Cast(m_iNameRecord.iAddr).Output(ipAddr);
// And connect to the IP address
// ConnectL(TInetAddr::Cast(m_iNameRecord.iAddr).Address());

nAdressIP = TInetAddr::Cast(m_iNameRecord.iAddr).Address();
}

// free the data
delete pIP;


return Connect(nAdressIP,iPort);
}

int CSocketTCPEngine::Send(const void *pBuffer, int cbBufSize)
{
TPtrC8 pSendBuf((const TUint8 *)pBuffer, cbBufSize);

TInt nSendBytes = 0;
nSendBytes = Send(pSendBuf, m_iSendLen);

return nSendBytes;
}

int CSocketTCPEngine::Receive(void *pBuffer, int cbBufSize)
{
TPtr8 pRecvBuf((TUint8 *)pBuffer, cbBufSize, cbBufSize);

TInt nRecvBytes = 0;
nRecvBytes = Receive((TDes8 &)pRecvBuf, m_iRecvLen);

return nRecvBytes;
}
Last edited by liuxg : 2003-05-16 at 04:05.
Reply With Quote

#4 Old 2003-05-16, 09:38

Join Date: Mar 2003
Posts: 3,175
Location: Beijing
Send a message via MSN to liuxg
liuxg's Avatar
liuxg
Offline
Forum Nokia Expert
Hi,

Based on the sample code from SDK, I have modified the code (\Symbian\6.1\Series60\Series60Ex\Sockets) and verified it in my place. I have seen the correct data length being displayed in my program.

Attached please find the code for your reference. It has two projects. One is client application, and the other one is server application. You can run the two applications in the same emulator. Once the connection is established. You can send data from Server to client. You will see the received data in the client application together with its length printed.

From the application, I did not see received data length equal to 0.

Should you have any problem in getting the applications running in your place, please let me know.

Hope this help!

Liuxg
Forum Nokia
Attached Files
File Type: zip sockets.zip (53.4 KB, 686 views)
Reply With Quote

#5 Old 2003-05-19, 12:59

Join Date: Apr 2003
Posts: 47
ttkttkttk
Offline
Registered User
非常感谢各位的解答,特别感谢liuxg,
在你的指导下问题终于得到了解决:现在我用
recvoneandmore得到正确的数据。
Last edited by liuxg : 2003-05-20 at 03:05.
Reply With Quote

#6 Old 2004-02-18, 08:55

Join Date: Aug 2003
Posts: 40
putek20
Offline
Registered User
on the zip file attached, when you compile the socket client it will look for Sockets.rsg, you must change the include file to Socketclient.rsg in order for it to work
Reply With Quote
Reply « Previous Thread | Next Thread »
Display Modes
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules

You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Forum Jump

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia