关于socket的两个问题,高分求教

elisa1 2008-09-05 04:45:02
初学socket编程,现在在做这样一个应用: 客户端向服务端发送一个字符串,服务端收到字符串后加工处理,进行一些操作,然后根据每个操作结果返回相应的字符串给客户端,客户端显示这些操作结果。现在出现了两个问题:

第一个问题: 客户端发送字符串后,有时侯能正常收到服务端的操作结果,有时侯收到的却是发送的字符串的一部分,这时候服务端收到的字符串也是不完整的,这是什么原因? 难道发送和接收的数据流是混在一起的? 这个问题该如何解决?

第二个问题,服务端第一次收到客户端的数据并处理后,服务端的CPU占用率就达到了50%,第二次收到数据并处理后就到了100%,即使我后面不做任何事,服务端也一直保持CPU占用率100%,结果当然可想而知,程序运行越来越慢,直到无法运行.这是怎么回事? 该怎样解决?

多谢各位指点迷津!!!!!!!!

服务端socket部分的代码如下:

//initialize Winsock
WSADATA wsaData;
int iRet=WSAStartup(MAKEWORD(2,2),&wsaData);
if(iRet!=NO_ERROR)
printf("Error at WSAStartup()\n");

//create a socket
SOCKET m_socket;
m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(m_socket==INVALID_SOCKET)
{
printf("Error at socket():%ld\n",WSAGetLastError());
WSACleanup();
return 0;
}
//bind a socket
sockaddr_in service;
service.sin_family=AF_INET;
service.sin_addr.s_addr=inet_addr("127.0.0.1"); //this is the IP of server
service.sin_port=htons(1788);

if(bind(m_socket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
{
printf("bind() failed.\n");
closesocket(m_socket);
return 0;
}
else
printf("bind OK.\n");

//listen on a socket
if(listen(m_socket,20)==SOCKET_ERROR)
printf("Error listening on socket.\n");
else
printf("listening ok.\n");

//accept a connection
SOCKET AcceptSocket;

printf("Waiting for a client to connect...\n");
while(1)
{
AcceptSocket=accept(m_socket,NULL,NULL);

printf("Client Connected.\n");

DWORD dwThreadId;
HANDLE hThread;

hThread=CreateThread(NULL,NULL,AnswerThread,(LPVOID)AcceptSocket,0,&dwThreadId);
if(hThread==NULL)
{
printf("CreatThread AnswerThread() failed.\n");
}
else
{
char recvBuffer[5000];
char nrArray[500][20];
bool print_or_fetch; //1 for printing, 0 for fetching
int i,s=0,t=0;
memset(recvBuffer,0,sizeof(recvBuffer));
memset(nrArray,0,sizeof(nrArray));
char path[255];
char copyfile[255];
char copyfile_info[255];
char folder_info[255];
memset(path,0,sizeof(path));
memset(copyfile,0,sizeof(copyfile));
memset(copyfile_info,0,sizeof(copyfile_info));
memset(folder_info,0,sizeof(folder_info));
printf("CreateThread OK.\n");
recv(AcceptSocket, recvBuffer, 5000,0);
for(i=0;i<=(int)strlen(recvBuffer);i++)
{
if(recvBuffer[i]=='[')
{
t=0;
}
else if(recvBuffer[i]==']')
{
s++;
}
else
{
nrArray[s][t]=recvBuffer[i];
t++;
}
}
for(i=0;i<s;i++)
{
if(strcmp(GetZPath(nrArray[i]),"Error!")==0)
{
printf("The number \"");
printf(nrArray[i]);
printf("\" was not found!");
strcpy_s(copyfile_info,_countof(copyfile_info),"The number \"");
strcat_s(copyfile_info,_countof(copyfile_info),nrArray[i]);
strcat_s(copyfile_info,_countof(copyfile_info),"\" was not found !");
}
else
{
strcpy_s(path,_countof(path),GetZPath(nrArray[i]));
strcat_s(path,_countof(path), "\\");
strcat_s(path,_countof(path), nrArray[i]);
strcat_s(path,_countof(path), "*.plt");
strcpy_s(copyfile,_countof(copyfile),"copy ");
strcat_s(copyfile,_countof(copyfile), path);
strcat_s(copyfile,_countof(copyfile), " d:\\data\\test_folder\\");

strcpy_s(copyfile_info,_countof(copyfile_info),"The number \"");
strcat_s(copyfile_info,_countof(copyfile_info),nrArray[i]);
strcat_s(copyfile_info,_countof(copyfile_info),"\" was found .");
}
send(AcceptSocket,copyfile_info,sizeof(copyfile_info),0);

}
shutdown(AcceptSocket,SD_BOTH);
closesocket(AcceptSocket);
}

}


客户端socket部分的代码如下:

Encoding^ ASCII = Encoding::ASCII;
array<Byte>^Zeichnnr = ASCII->GetBytes(tmpstr); //tmpstr是要发送的字符串
Socket^ mySocket = nullptr;
IPEndPoint^ hostEndPoint;
IPAddress^ hostAddress = nullptr;
int conPort = 1788;
array<Byte>^ recvBuffer=gcnew array<Byte>(255);
int recByte;
String^ str_Status="";


// Get the DNS IP addresses associated with the host.
array<IPAddress^>^IPaddress = Dns::GetHostAddresses("127.0.0.1");
// Evaluate the socket and receiving host IPAddress and IPEndPoint.

hostAddress =IPaddress[0];
hostEndPoint = gcnew IPEndPoint(hostAddress,conPort );

// Creates the Socket to send data over a TCP connection.
mySocket = gcnew Socket( AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp );


// Connect to the host using its IPEndPoint.
try
{
mySocket->Connect(hostEndPoint);
if (!mySocket->Connected)
{

// Connection failed

LB_Status->Items->Add( String::Format( "Error at binding!" ) );
mySocket = nullptr;

}
else if(mySocket->Send(Zeichnnr,Zeichnnr->Length,SocketFlags::None)<=0)
{
LB_Status->Items->Add( String::Format( "Error at sending!" ) );
}
Zeichnnr->Clear(Zeichnnr,0,Zeichnnr->Length);

}
catch(SocketException^)
{

LB_Status->Items->Add( String::Format( "Error at binding!" ) );
mySocket = nullptr;
}
recvBuffer->Clear(recvBuffer,0,255);



try
{
int i=0;
while(1)
{
recByte=mySocket->Receive(recvBuffer,recvBuffer->Length,SocketFlags::None);
if(recByte>0)
{
str_Status=String::Copy(ASCII->GetString( recvBuffer, 0, recvBuffer->Length ));
LB_Status->Items->Add(String::Format(str_Status));
LB_Status->TopIndex=i;
LB_Status->Refresh();
i++;
}
else
break;
}
}
catch(NullReferenceException^ e)
{

LB_Status->Items->Add( String::Format( e->ToString() ) );
mySocket = nullptr;
}

mySocket->Shutdown(SocketShutdown::Both);
mySocket->Close();

...全文
192 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
elisa1 2008-09-09
  • 打赏
  • 举报
回复
问题自己解决了,虽然各位都未能给出原因和解决办法,但是几个朋友给了我启发,多谢,结帖了。
elisa1 2008-09-08
  • 打赏
  • 举报
回复
关于第二个问题,跟踪调试时发现的一些新情况:

服务器端启动时,运行到accept函数,阻塞,等待客户端的数据,一切正常,服务端基本不占cpu。

客户端第一次发送数据,服务端接收,然后 处理数据完成,这其间服务端占用cpu也很低。

服务端处理完第一次收到的数据,再次回到运行accept函数等待客户端的数据时,cpu占用率急剧上升为50%(双核,单核实际上该是100%),并不再降低。

各位请发表意见,为什么会这样?
cattycat 2008-09-08
  • 打赏
  • 举报
回复
阻塞式本身可能比较费cpu,它是一种忙等待的方式。可以考虑非阻塞方式。
hThread=CreateThread(NULL,NULL,AnswerThread,(LPVOID)AcceptSocket,0,&dwThreadId);
应该有AnswerThread一个函数吧,在这个里边处理接收到的数据,不知道你贴的代码怎么没有?
elisa1 2008-09-08
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hqin6 的回复:]
第一个问题:丢包了?
[/Quote]

就是不知道怎么回事。我刚开始用socket编程不久。
客户端send的东西居然有一部分被自己receive到了,好奇怪
怎么检查丢包了没有?
elisa1 2008-09-08
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 zmlovelx 的回复:]
引用 3 楼 elisa1 的回复:
引用 1 楼 cwc270 的回复:
hThread=CreateThread(NULL,NULL,AnswerThread,(LPVOID)AcceptSocket,0,&dwThreadId);
开辟的线程干什么用的?
下面已经有代码接受数据,并处理返回了吧?
开辟线程是为了为多个客户端访问服务端准备的

可以考虑用select
[/Quote]

考虑过,但是使用方只让我用一个端口,也就是说只能建立一个socket,所以没法select.
elisa1 2008-09-08
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 51365133 的回复:]
C/C++ codewhile(1)
{
Sleep(500);//try
...
}
[/Quote]

thanks, I will try.
太乙 2008-09-08
  • 打赏
  • 举报
回复
第一个问题:丢包了?
帅得不敢出门 2008-09-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 elisa1 的回复:]
引用 1 楼 cwc270 的回复:
hThread=CreateThread(NULL,NULL,AnswerThread,(LPVOID)AcceptSocket,0,&dwThreadId);
开辟的线程干什么用的?
下面已经有代码接受数据,并处理返回了吧?
开辟线程是为了为多个客户端访问服务端准备的
[/Quote]
可以考虑用select
51365133 2008-09-08
  • 打赏
  • 举报
回复
while(1)
{
Sleep(500);//try
...
}
星羽 2008-09-05
  • 打赏
  • 举报
回复
代码好多好乱啊 - -
meihuiyu 2008-09-05
  • 打赏
  • 举报
回复
up
laibach0304 2008-09-05
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 elisa1 的回复:]
引用 2 楼 zjl_1026_2001 的回复:
楼主把版排一下吧 我晚点来看看 这样太累了


呵呵,多谢了
我是排好了发的,可是怎么发上代码部分来全变了,全部左对齐了? 请教一下,这里怎么排版?
[/Quote]
点“插入源代码”
kelvin_2013 2008-09-05
  • 打赏
  • 举报
回复
mark
elisa1 2008-09-05
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 zjl_1026_2001 的回复:]
楼主把版排一下吧 我晚点来看看 这样太累了
[/Quote]

呵呵,多谢了
我是排好了发的,可是怎么发上代码部分来全变了,全部左对齐了? 请教一下,这里怎么排版?
elisa1 2008-09-05
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 cwc270 的回复:]
hThread=CreateThread(NULL,NULL,AnswerThread,(LPVOID)AcceptSocket,0,&dwThreadId);
开辟的线程干什么用的?
下面已经有代码接受数据,并处理返回了吧?
[/Quote]


开辟线程是为了为多个客户端访问服务端准备的
沙漠里的海豚 2008-09-05
  • 打赏
  • 举报
回复
楼主把版排一下吧 我晚点来看看 这样太累了
cwc270 2008-09-05
  • 打赏
  • 举报
回复
hThread=CreateThread(NULL,NULL,AnswerThread,(LPVOID)AcceptSocket,0,&dwThreadId);
开辟的线程干什么用的?
下面已经有代码接受数据,并处理返回了吧?

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧