27 个解决方案
#1
我先自己顶
#2
有人吗
#3
怎么没人回帖子啊
#4
一定是你的代码有问题,你说的太笼统了,也没有代码,没法说,要学会说清问题
#5
跟踪一下你发送了多少个字节,是否两个结构体都成功的发送出去了。
接收时跟踪一下实际接收了多少个字节
接收时跟踪一下实际接收了多少个字节
#6
你用tcp还是udp发送的?用udp的话丢包的现象本来就时有发生。
#7
证明你收到了第一个消息缓冲以后没有继续收第二个消息。看代码。
#8
我是在一个函数中用的两个send函数,这算同时吗?
#9
你把你的收发的代码贴一下吧。
#10
如果是两个send函数发送两个同类型的结构体,再去接收这两个同类型的结构体,一般要如何操作呢?
#11
send 函数会返回实际的发送字节数,除非你的send数据流非常大,例如一次发送8192字节,否则,一般的小于1024字节的发送都可以单次完成。
MyStruct st;
send(sock, &st, sizeof(MyStruct), 0);
MyStruct st;
send(sock, &st, sizeof(MyStruct), 0);
#12
发送端代码:
void CFiveDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if((m_bStart==true)&&(m_bReady==true))
{
if(m_Myturn==m_turn)
{
if(point.x>536||point.y>536||point.x<11||point.y<11)
return;
int x,y;
x=(point.x-11)/35;
y=(point.y-11)/35;
gameinfo info;
chessboard m_chessboard;
//发送棋子信息到另一方
if(!m_match.CanDown(x,y,m_turn))
return;
info.m_x=x;
info.m_y=y;
info.m_turn=m_turn;
info.cmd=1;
info.type=2;
if(!m_bClient)//服务器
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&info,sizeof(info),0);
}
m_chessboard.x=x;
m_chessboard.y=y;
m_chessboardlist.AddTail(m_chessboard);
}
else//客户端
{
send(m_ClientSocket.m_hSocket,(char*)&info,sizeof(info),0);
}
OnPaint();
PlaySound((LPCTSTR)IDR_DOWNCHESS,AfxGetInstanceHandle(),SND_RESOURCE | SND_ASYNC);
m_Myturn=m_Myturn%2+1;//交换次序
if(m_match.IsWin(m_turn))
{
InvalidateRect(&m_rect,false);
m_bStart=false;
m_bReady=false;
m_Myturn=2;
SetDlgItemText(IDC_TEXT1,m_username);
if(!m_bClient)
SetDlgItemText(IDC_TEXT2,playerinfo[1].name);
else
SetDlgItemText(IDC_TEXT2,m_hostname);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
//更新列表中本方的玩家信息
CString new_win,new_score,new_lost;
for(int j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=m_username);j++);
new_win.Format("%d",atoi(m_list1.GetItemText(j,2))+1);
new_score.Format("%d",atoi(m_list1.GetItemText(j,1))+10);
m_list1.SetItemText(j,1,new_score);
m_list1.SetItemText(j,2,new_win);
m_list1.SetItemText(j,4,GetGrade(atoi(m_list1.GetItemText(j,1))));
//更新列表中对方的玩家信息
if(!m_bClient)
{
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=playerinfo[1].name);j++);
}
else
{
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=m_hostname);j++);
}
new_lost.Format("%d",atoi(m_list1.GetItemText(j,3))+1);
new_score.Format("%d",atoi(m_list1.GetItemText(j,1))-10);
m_list1.SetItemText(j,1,new_score);
m_list1.SetItemText(j,3,new_lost);
m_list1.SetItemText(j,4,GetGrade(atoi(m_list1.GetItemText(j,1))));
//将所有列表信息发送到另一端
sendinfo over_info1;
for(int i=0;i<m_list1.GetItemCount();i++)
{
memcpy(over_info1.m_info.name,m_list1.GetItemText(i,0),
m_list1.GetItemText(i,0).GetLength()+1);
over_info1.m_info.m_win=atoi(m_list1.GetItemText(i,2));
over_info1.m_info.m_lost=atoi(m_list1.GetItemText(i,3));
over_info1.m_info.score=atoi(m_list1.GetItemText(i,1));
memcpy(over_info1.m_info.grade,m_list1.GetItemText(i,4),
m_list1.GetItemText(i,4).GetLength()+1);
over_info1.cmd=2;
over_info1.type=3;
if(!m_bClient)
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&over_info1,sizeof(over_info1),0);
}
}
else
{
send(m_ClientSocket.m_hSocket,(char*)&over_info1,sizeof(over_info1),0);
}
}
//将输赢信息发给对方
info.cmd=1;
info.type=3;
info.m_win=0;
Sleep(1000);
/*这个函数必须要写,因为在这个函数中将要发送两个同种类型的结构体,
*但它的消息编号不同,在第一个结构体被发送过去的时候,如果没有用
*这个函数,第二个结构体在发送过去后,第一个结构体还未处理完。此时
*会产生数据抛弃的现象。因此这个函数避免了这种情况,也避免了两个消
*息一起接收。使得在第一个结构体接收后缓冲区被释放出来,第二个结构体
*被顺利接收。
*/
if(!m_bClient)//服务器
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&info,sizeof(info),0);
}
}
else//客户端
{
send(m_ClientSocket.m_hSocket,(char*)&info,sizeof(info),0);
}
}
}
}
CDialog::OnLButtonDown(nFlags, point);
}
void CFiveDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if((m_bStart==true)&&(m_bReady==true))
{
if(m_Myturn==m_turn)
{
if(point.x>536||point.y>536||point.x<11||point.y<11)
return;
int x,y;
x=(point.x-11)/35;
y=(point.y-11)/35;
gameinfo info;
chessboard m_chessboard;
//发送棋子信息到另一方
if(!m_match.CanDown(x,y,m_turn))
return;
info.m_x=x;
info.m_y=y;
info.m_turn=m_turn;
info.cmd=1;
info.type=2;
if(!m_bClient)//服务器
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&info,sizeof(info),0);
}
m_chessboard.x=x;
m_chessboard.y=y;
m_chessboardlist.AddTail(m_chessboard);
}
else//客户端
{
send(m_ClientSocket.m_hSocket,(char*)&info,sizeof(info),0);
}
OnPaint();
PlaySound((LPCTSTR)IDR_DOWNCHESS,AfxGetInstanceHandle(),SND_RESOURCE | SND_ASYNC);
m_Myturn=m_Myturn%2+1;//交换次序
if(m_match.IsWin(m_turn))
{
InvalidateRect(&m_rect,false);
m_bStart=false;
m_bReady=false;
m_Myturn=2;
SetDlgItemText(IDC_TEXT1,m_username);
if(!m_bClient)
SetDlgItemText(IDC_TEXT2,playerinfo[1].name);
else
SetDlgItemText(IDC_TEXT2,m_hostname);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
//更新列表中本方的玩家信息
CString new_win,new_score,new_lost;
for(int j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=m_username);j++);
new_win.Format("%d",atoi(m_list1.GetItemText(j,2))+1);
new_score.Format("%d",atoi(m_list1.GetItemText(j,1))+10);
m_list1.SetItemText(j,1,new_score);
m_list1.SetItemText(j,2,new_win);
m_list1.SetItemText(j,4,GetGrade(atoi(m_list1.GetItemText(j,1))));
//更新列表中对方的玩家信息
if(!m_bClient)
{
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=playerinfo[1].name);j++);
}
else
{
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=m_hostname);j++);
}
new_lost.Format("%d",atoi(m_list1.GetItemText(j,3))+1);
new_score.Format("%d",atoi(m_list1.GetItemText(j,1))-10);
m_list1.SetItemText(j,1,new_score);
m_list1.SetItemText(j,3,new_lost);
m_list1.SetItemText(j,4,GetGrade(atoi(m_list1.GetItemText(j,1))));
//将所有列表信息发送到另一端
sendinfo over_info1;
for(int i=0;i<m_list1.GetItemCount();i++)
{
memcpy(over_info1.m_info.name,m_list1.GetItemText(i,0),
m_list1.GetItemText(i,0).GetLength()+1);
over_info1.m_info.m_win=atoi(m_list1.GetItemText(i,2));
over_info1.m_info.m_lost=atoi(m_list1.GetItemText(i,3));
over_info1.m_info.score=atoi(m_list1.GetItemText(i,1));
memcpy(over_info1.m_info.grade,m_list1.GetItemText(i,4),
m_list1.GetItemText(i,4).GetLength()+1);
over_info1.cmd=2;
over_info1.type=3;
if(!m_bClient)
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&over_info1,sizeof(over_info1),0);
}
}
else
{
send(m_ClientSocket.m_hSocket,(char*)&over_info1,sizeof(over_info1),0);
}
}
//将输赢信息发给对方
info.cmd=1;
info.type=3;
info.m_win=0;
Sleep(1000);
/*这个函数必须要写,因为在这个函数中将要发送两个同种类型的结构体,
*但它的消息编号不同,在第一个结构体被发送过去的时候,如果没有用
*这个函数,第二个结构体在发送过去后,第一个结构体还未处理完。此时
*会产生数据抛弃的现象。因此这个函数避免了这种情况,也避免了两个消
*息一起接收。使得在第一个结构体接收后缓冲区被释放出来,第二个结构体
*被顺利接收。
*/
if(!m_bClient)//服务器
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&info,sizeof(info),0);
}
}
else//客户端
{
send(m_ClientSocket.m_hSocket,(char*)&info,sizeof(info),0);
}
}
}
}
CDialog::OnLButtonDown(nFlags, point);
}
#13
接收端代码:
void CFiveDlg::OnAcceptMessage(WPARAM wParam,LPARAM lParam)
{
int j;
sendinfo info;
gameinfo game_info;
CString m_Msg,m_name;
CEdit * output=NULL;
switch(lParam)
{
case FD_READ:
if(m_connection==wParam)
{
if(SOCKET_ERROR!=recv(m_connection,(char*)&info,sizeof(info),0))
{
if(info.cmd==2)
{
switch(info.type)
{
case 0: //当为0,表示用户进入
{
m_name=info.name;
m_Msg=m_name+"进入了游戏房间!\r\n";
//储存客户端的玩家信息
playerinfo[1].score=0;
playerinfo[1].m_win=0;
playerinfo[1].m_lost=0;
memcpy(playerinfo[1].grade,"菜鸟",20);
memcpy(playerinfo[1].name,m_name,m_name.GetLength()+1);
//发送所有玩家信息到新客户端
for(j=0;j<2;j++)
{
if(strcmp(playerinfo[j].name,""))
{
sendinfo infolist;
infolist.m_info=playerinfo[j];
infolist.type=0;
infolist.cmd=2;
memcpy(infolist.msg,"",100);
if(SOCKET_ERROR==send(m_connection,(char*)&infolist,
sizeof(infolist),0))
{
MessageBox("发送数据失败!");
return;
}
}
}
//当玩家进入时更新服务器信息
SetDlgItemText(IDC_TEXT2,m_name);
GetDlgItem(IDC_START)->EnableWindow(true);
m_sShowText=m_sShowText+m_Msg;
UpdateData(false);
CEdit * output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
//主机加所有玩家入列表
m_list1.DeleteAllItems();
index=-1;
for(j=0;j<2;j++)
{
if(strcmp(playerinfo[j].name,""))
{
InsertList(index,playerinfo[j]);
}
}
}
break;
case 1://当为1, 表示和大家聊天
m_sShowText=m_sShowText+info.msg;
UpdateData(false);
output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
break;
case 3://当为3、游戏结束后刷新玩家列表信息
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=info.m_info.name);j++);
UpdateList(info.m_info,j);
break;
}//end switch
}//end if
else
{
chessboard m_chessboard;
CString text1,text2;
game_info=*((gameinfo*)&info);
switch(game_info.type)
{
case 1://开始信息
m_WhiteOver=false;
m_BlackOver=false;
m_turn=game_info.m_turn;
text2=playerinfo[1].name;
if(game_info.m_turn==2)
{
text1=m_username+"\r\n"+"\r\n"+"黑方";
text2=text2+"\r\n"+"\r\n"+"白方";
}
if(game_info.m_turn==1)
{
text1=m_username+"\r\n"+"\r\n"+"白方";
text2=text2+"\r\n"+"\r\n"+"黑方";
}
GetDlgItem(IDC_TEXT1)->SetWindowText(text1);
GetDlgItem(IDC_TEXT2)->SetWindowText(text2);
m_match.Clear();
InvalidateRect(&m_rect,false);
break;
case 2://表示为游戏中棋子信息。
if(m_match.CanDown(game_info.m_x,game_info.m_y,game_info.m_turn))
{
m_chessboard.x=game_info.m_x;
m_chessboard.y=game_info.m_y;
m_chessboardlist.AddTail(m_chessboard);
OnPaint();
m_Myturn=game_info.m_turn%2+1;
}
break;
case 3://表示为游戏结束信息.
if(game_info.m_win==1)
m_WhiteOver=true;
if(game_info.m_win==2)
m_BlackOver=true;
SetDlgItemText(IDC_TEXT1,m_username);
SetDlgItemText(IDC_TEXT2,playerinfo[1].name);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
InvalidateRect(&m_rect,false);
m_Myturn=2;
m_bStart=false;
m_bReady=false;
break;
case 4://表示被动方通知主动方已经连接好
m_bReady=true;
break;
case 5:
{
chessboard m_chessboard;
if(m_chessboardlist.GetCount()<2)
return;
//刷新本方
for(int i=0;i<2;i++)
{
POSITION pos=m_chessboardlist.GetTailPosition();
m_chessboard=m_chessboardlist.GetAt(pos);
m_match.chessboard[m_chessboard.x][m_chessboard.y]=0;
m_chessboardlist.RemoveTail();
game_info.cmd=1;
game_info.type=5;
game_info.m_x=m_chessboard.x;
game_info.m_y=m_chessboard.y;
send(m_connection,(char*)&game_info,sizeof(game_info),0);
Sleep(10);
}
InvalidateRect(&m_rect,false);
break;
}
}//end switch
}//end else
return;
}//end if
}//end if
break;
case FD_CLOSE:
closesocket(m_connection);
m_connection=INVALID_SOCKET;
CString str,name;
name=playerinfo[1].name;
str=name+"离开游戏房间!\r\n";
memcpy(playerinfo[1].name,"",20);
//服务器更新数据
m_sShowText=m_sShowText+str;
for(int j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=name);j++);
m_list1.DeleteItem(j);
UpdateData(false);
index--;
m_match.Clear();
InvalidateRect(&m_rect,false);
SetDlgItemText(IDC_TEXT2,"");
SetDlgItemText(IDC_TEXT1,m_username);
GetDlgItem(IDC_START)->EnableWindow(false);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
CEdit * output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
break;
}//end switch
}
void CFiveDlg::OnAcceptMessage(WPARAM wParam,LPARAM lParam)
{
int j;
sendinfo info;
gameinfo game_info;
CString m_Msg,m_name;
CEdit * output=NULL;
switch(lParam)
{
case FD_READ:
if(m_connection==wParam)
{
if(SOCKET_ERROR!=recv(m_connection,(char*)&info,sizeof(info),0))
{
if(info.cmd==2)
{
switch(info.type)
{
case 0: //当为0,表示用户进入
{
m_name=info.name;
m_Msg=m_name+"进入了游戏房间!\r\n";
//储存客户端的玩家信息
playerinfo[1].score=0;
playerinfo[1].m_win=0;
playerinfo[1].m_lost=0;
memcpy(playerinfo[1].grade,"菜鸟",20);
memcpy(playerinfo[1].name,m_name,m_name.GetLength()+1);
//发送所有玩家信息到新客户端
for(j=0;j<2;j++)
{
if(strcmp(playerinfo[j].name,""))
{
sendinfo infolist;
infolist.m_info=playerinfo[j];
infolist.type=0;
infolist.cmd=2;
memcpy(infolist.msg,"",100);
if(SOCKET_ERROR==send(m_connection,(char*)&infolist,
sizeof(infolist),0))
{
MessageBox("发送数据失败!");
return;
}
}
}
//当玩家进入时更新服务器信息
SetDlgItemText(IDC_TEXT2,m_name);
GetDlgItem(IDC_START)->EnableWindow(true);
m_sShowText=m_sShowText+m_Msg;
UpdateData(false);
CEdit * output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
//主机加所有玩家入列表
m_list1.DeleteAllItems();
index=-1;
for(j=0;j<2;j++)
{
if(strcmp(playerinfo[j].name,""))
{
InsertList(index,playerinfo[j]);
}
}
}
break;
case 1://当为1, 表示和大家聊天
m_sShowText=m_sShowText+info.msg;
UpdateData(false);
output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
break;
case 3://当为3、游戏结束后刷新玩家列表信息
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=info.m_info.name);j++);
UpdateList(info.m_info,j);
break;
}//end switch
}//end if
else
{
chessboard m_chessboard;
CString text1,text2;
game_info=*((gameinfo*)&info);
switch(game_info.type)
{
case 1://开始信息
m_WhiteOver=false;
m_BlackOver=false;
m_turn=game_info.m_turn;
text2=playerinfo[1].name;
if(game_info.m_turn==2)
{
text1=m_username+"\r\n"+"\r\n"+"黑方";
text2=text2+"\r\n"+"\r\n"+"白方";
}
if(game_info.m_turn==1)
{
text1=m_username+"\r\n"+"\r\n"+"白方";
text2=text2+"\r\n"+"\r\n"+"黑方";
}
GetDlgItem(IDC_TEXT1)->SetWindowText(text1);
GetDlgItem(IDC_TEXT2)->SetWindowText(text2);
m_match.Clear();
InvalidateRect(&m_rect,false);
break;
case 2://表示为游戏中棋子信息。
if(m_match.CanDown(game_info.m_x,game_info.m_y,game_info.m_turn))
{
m_chessboard.x=game_info.m_x;
m_chessboard.y=game_info.m_y;
m_chessboardlist.AddTail(m_chessboard);
OnPaint();
m_Myturn=game_info.m_turn%2+1;
}
break;
case 3://表示为游戏结束信息.
if(game_info.m_win==1)
m_WhiteOver=true;
if(game_info.m_win==2)
m_BlackOver=true;
SetDlgItemText(IDC_TEXT1,m_username);
SetDlgItemText(IDC_TEXT2,playerinfo[1].name);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
InvalidateRect(&m_rect,false);
m_Myturn=2;
m_bStart=false;
m_bReady=false;
break;
case 4://表示被动方通知主动方已经连接好
m_bReady=true;
break;
case 5:
{
chessboard m_chessboard;
if(m_chessboardlist.GetCount()<2)
return;
//刷新本方
for(int i=0;i<2;i++)
{
POSITION pos=m_chessboardlist.GetTailPosition();
m_chessboard=m_chessboardlist.GetAt(pos);
m_match.chessboard[m_chessboard.x][m_chessboard.y]=0;
m_chessboardlist.RemoveTail();
game_info.cmd=1;
game_info.type=5;
game_info.m_x=m_chessboard.x;
game_info.m_y=m_chessboard.y;
send(m_connection,(char*)&game_info,sizeof(game_info),0);
Sleep(10);
}
InvalidateRect(&m_rect,false);
break;
}
}//end switch
}//end else
return;
}//end if
}//end if
break;
case FD_CLOSE:
closesocket(m_connection);
m_connection=INVALID_SOCKET;
CString str,name;
name=playerinfo[1].name;
str=name+"离开游戏房间!\r\n";
memcpy(playerinfo[1].name,"",20);
//服务器更新数据
m_sShowText=m_sShowText+str;
for(int j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=name);j++);
m_list1.DeleteItem(j);
UpdateData(false);
index--;
m_match.Clear();
InvalidateRect(&m_rect,false);
SetDlgItemText(IDC_TEXT2,"");
SetDlgItemText(IDC_TEXT1,m_username);
GetDlgItem(IDC_START)->EnableWindow(false);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
CEdit * output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
break;
}//end switch
}
#14
代码太长了,不好意思。
#15
晕,代码太长,没仔细看。
一次send对应一次recv,成功接收到一次send,recv就自动返回了,如果在同一函数内对内一接收方send两次,那对方同样需要同一函数内recv两次
我数了一下,你好像send了两次,而之recv了一次,那另一次send的东西由谁来接收呢?
一次send对应一次recv,成功接收到一次send,recv就自动返回了,如果在同一函数内对内一接收方send两次,那对方同样需要同一函数内recv两次
我数了一下,你好像send了两次,而之recv了一次,那另一次send的东西由谁来接收呢?
#16
另外,好像你的send和recv都是在主线程里干的,而且你用的好像是阻塞方式了,主程是不是经常就这样锁住了,莫非阁下在做五子棋什么的小游戏。。。?
#17
我用的异步选择方式啊,在做个五子棋
#18
FD_READ 我是先接过来,再去判断可以吗?
#19
还在吗?
#20
调用两次OnAcceptMessage()
你的函数一次OnAcceptMessage()只接收一次Socket信息,发送方每发送一次信息,这边都要调用一次OnAcceptMessage();
其实这个问题在MFC框架中是不存在的,可以在OnReceive()中调用,MFC会每接收一次信息即调用一次OnReceive(),但是你自己处理的过程就不同了。
你的函数一次OnAcceptMessage()只接收一次Socket信息,发送方每发送一次信息,这边都要调用一次OnAcceptMessage();
其实这个问题在MFC框架中是不存在的,可以在OnReceive()中调用,MFC会每接收一次信息即调用一次OnReceive(),但是你自己处理的过程就不同了。
#21
up
#22
我用API写的
#23
#24
狂晕
#25
你的CODE里面的send有点问题 ,unblocking模式有可能导致你在还未完全收到Message之前,就已经返回。mybe, who could got it really?
#26
那应该如何解决呢?我用线程控制住发送端可以吗?
#27
继续关注中,我用Sleep函数加在send函数之间,可以解决问题,可是这样等待时间太长了
#28
还是用blocking模式比较好,send和recv放在独立的线程中。
或者改用mfc的CAsyncSock,异步方式利用里面的事件做处理方便多了。
或者改用mfc的CAsyncSock,异步方式利用里面的事件做处理方便多了。
#1
我先自己顶
#2
有人吗
#3
怎么没人回帖子啊
#4
一定是你的代码有问题,你说的太笼统了,也没有代码,没法说,要学会说清问题
#5
跟踪一下你发送了多少个字节,是否两个结构体都成功的发送出去了。
接收时跟踪一下实际接收了多少个字节
接收时跟踪一下实际接收了多少个字节
#6
你用tcp还是udp发送的?用udp的话丢包的现象本来就时有发生。
#7
证明你收到了第一个消息缓冲以后没有继续收第二个消息。看代码。
#8
我是在一个函数中用的两个send函数,这算同时吗?
#9
你把你的收发的代码贴一下吧。
#10
如果是两个send函数发送两个同类型的结构体,再去接收这两个同类型的结构体,一般要如何操作呢?
#11
send 函数会返回实际的发送字节数,除非你的send数据流非常大,例如一次发送8192字节,否则,一般的小于1024字节的发送都可以单次完成。
MyStruct st;
send(sock, &st, sizeof(MyStruct), 0);
MyStruct st;
send(sock, &st, sizeof(MyStruct), 0);
#12
发送端代码:
void CFiveDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if((m_bStart==true)&&(m_bReady==true))
{
if(m_Myturn==m_turn)
{
if(point.x>536||point.y>536||point.x<11||point.y<11)
return;
int x,y;
x=(point.x-11)/35;
y=(point.y-11)/35;
gameinfo info;
chessboard m_chessboard;
//发送棋子信息到另一方
if(!m_match.CanDown(x,y,m_turn))
return;
info.m_x=x;
info.m_y=y;
info.m_turn=m_turn;
info.cmd=1;
info.type=2;
if(!m_bClient)//服务器
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&info,sizeof(info),0);
}
m_chessboard.x=x;
m_chessboard.y=y;
m_chessboardlist.AddTail(m_chessboard);
}
else//客户端
{
send(m_ClientSocket.m_hSocket,(char*)&info,sizeof(info),0);
}
OnPaint();
PlaySound((LPCTSTR)IDR_DOWNCHESS,AfxGetInstanceHandle(),SND_RESOURCE | SND_ASYNC);
m_Myturn=m_Myturn%2+1;//交换次序
if(m_match.IsWin(m_turn))
{
InvalidateRect(&m_rect,false);
m_bStart=false;
m_bReady=false;
m_Myturn=2;
SetDlgItemText(IDC_TEXT1,m_username);
if(!m_bClient)
SetDlgItemText(IDC_TEXT2,playerinfo[1].name);
else
SetDlgItemText(IDC_TEXT2,m_hostname);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
//更新列表中本方的玩家信息
CString new_win,new_score,new_lost;
for(int j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=m_username);j++);
new_win.Format("%d",atoi(m_list1.GetItemText(j,2))+1);
new_score.Format("%d",atoi(m_list1.GetItemText(j,1))+10);
m_list1.SetItemText(j,1,new_score);
m_list1.SetItemText(j,2,new_win);
m_list1.SetItemText(j,4,GetGrade(atoi(m_list1.GetItemText(j,1))));
//更新列表中对方的玩家信息
if(!m_bClient)
{
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=playerinfo[1].name);j++);
}
else
{
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=m_hostname);j++);
}
new_lost.Format("%d",atoi(m_list1.GetItemText(j,3))+1);
new_score.Format("%d",atoi(m_list1.GetItemText(j,1))-10);
m_list1.SetItemText(j,1,new_score);
m_list1.SetItemText(j,3,new_lost);
m_list1.SetItemText(j,4,GetGrade(atoi(m_list1.GetItemText(j,1))));
//将所有列表信息发送到另一端
sendinfo over_info1;
for(int i=0;i<m_list1.GetItemCount();i++)
{
memcpy(over_info1.m_info.name,m_list1.GetItemText(i,0),
m_list1.GetItemText(i,0).GetLength()+1);
over_info1.m_info.m_win=atoi(m_list1.GetItemText(i,2));
over_info1.m_info.m_lost=atoi(m_list1.GetItemText(i,3));
over_info1.m_info.score=atoi(m_list1.GetItemText(i,1));
memcpy(over_info1.m_info.grade,m_list1.GetItemText(i,4),
m_list1.GetItemText(i,4).GetLength()+1);
over_info1.cmd=2;
over_info1.type=3;
if(!m_bClient)
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&over_info1,sizeof(over_info1),0);
}
}
else
{
send(m_ClientSocket.m_hSocket,(char*)&over_info1,sizeof(over_info1),0);
}
}
//将输赢信息发给对方
info.cmd=1;
info.type=3;
info.m_win=0;
Sleep(1000);
/*这个函数必须要写,因为在这个函数中将要发送两个同种类型的结构体,
*但它的消息编号不同,在第一个结构体被发送过去的时候,如果没有用
*这个函数,第二个结构体在发送过去后,第一个结构体还未处理完。此时
*会产生数据抛弃的现象。因此这个函数避免了这种情况,也避免了两个消
*息一起接收。使得在第一个结构体接收后缓冲区被释放出来,第二个结构体
*被顺利接收。
*/
if(!m_bClient)//服务器
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&info,sizeof(info),0);
}
}
else//客户端
{
send(m_ClientSocket.m_hSocket,(char*)&info,sizeof(info),0);
}
}
}
}
CDialog::OnLButtonDown(nFlags, point);
}
void CFiveDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if((m_bStart==true)&&(m_bReady==true))
{
if(m_Myturn==m_turn)
{
if(point.x>536||point.y>536||point.x<11||point.y<11)
return;
int x,y;
x=(point.x-11)/35;
y=(point.y-11)/35;
gameinfo info;
chessboard m_chessboard;
//发送棋子信息到另一方
if(!m_match.CanDown(x,y,m_turn))
return;
info.m_x=x;
info.m_y=y;
info.m_turn=m_turn;
info.cmd=1;
info.type=2;
if(!m_bClient)//服务器
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&info,sizeof(info),0);
}
m_chessboard.x=x;
m_chessboard.y=y;
m_chessboardlist.AddTail(m_chessboard);
}
else//客户端
{
send(m_ClientSocket.m_hSocket,(char*)&info,sizeof(info),0);
}
OnPaint();
PlaySound((LPCTSTR)IDR_DOWNCHESS,AfxGetInstanceHandle(),SND_RESOURCE | SND_ASYNC);
m_Myturn=m_Myturn%2+1;//交换次序
if(m_match.IsWin(m_turn))
{
InvalidateRect(&m_rect,false);
m_bStart=false;
m_bReady=false;
m_Myturn=2;
SetDlgItemText(IDC_TEXT1,m_username);
if(!m_bClient)
SetDlgItemText(IDC_TEXT2,playerinfo[1].name);
else
SetDlgItemText(IDC_TEXT2,m_hostname);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
//更新列表中本方的玩家信息
CString new_win,new_score,new_lost;
for(int j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=m_username);j++);
new_win.Format("%d",atoi(m_list1.GetItemText(j,2))+1);
new_score.Format("%d",atoi(m_list1.GetItemText(j,1))+10);
m_list1.SetItemText(j,1,new_score);
m_list1.SetItemText(j,2,new_win);
m_list1.SetItemText(j,4,GetGrade(atoi(m_list1.GetItemText(j,1))));
//更新列表中对方的玩家信息
if(!m_bClient)
{
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=playerinfo[1].name);j++);
}
else
{
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=m_hostname);j++);
}
new_lost.Format("%d",atoi(m_list1.GetItemText(j,3))+1);
new_score.Format("%d",atoi(m_list1.GetItemText(j,1))-10);
m_list1.SetItemText(j,1,new_score);
m_list1.SetItemText(j,3,new_lost);
m_list1.SetItemText(j,4,GetGrade(atoi(m_list1.GetItemText(j,1))));
//将所有列表信息发送到另一端
sendinfo over_info1;
for(int i=0;i<m_list1.GetItemCount();i++)
{
memcpy(over_info1.m_info.name,m_list1.GetItemText(i,0),
m_list1.GetItemText(i,0).GetLength()+1);
over_info1.m_info.m_win=atoi(m_list1.GetItemText(i,2));
over_info1.m_info.m_lost=atoi(m_list1.GetItemText(i,3));
over_info1.m_info.score=atoi(m_list1.GetItemText(i,1));
memcpy(over_info1.m_info.grade,m_list1.GetItemText(i,4),
m_list1.GetItemText(i,4).GetLength()+1);
over_info1.cmd=2;
over_info1.type=3;
if(!m_bClient)
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&over_info1,sizeof(over_info1),0);
}
}
else
{
send(m_ClientSocket.m_hSocket,(char*)&over_info1,sizeof(over_info1),0);
}
}
//将输赢信息发给对方
info.cmd=1;
info.type=3;
info.m_win=0;
Sleep(1000);
/*这个函数必须要写,因为在这个函数中将要发送两个同种类型的结构体,
*但它的消息编号不同,在第一个结构体被发送过去的时候,如果没有用
*这个函数,第二个结构体在发送过去后,第一个结构体还未处理完。此时
*会产生数据抛弃的现象。因此这个函数避免了这种情况,也避免了两个消
*息一起接收。使得在第一个结构体接收后缓冲区被释放出来,第二个结构体
*被顺利接收。
*/
if(!m_bClient)//服务器
{
if(m_connection!=INVALID_SOCKET)
{
send(m_connection,(char*)&info,sizeof(info),0);
}
}
else//客户端
{
send(m_ClientSocket.m_hSocket,(char*)&info,sizeof(info),0);
}
}
}
}
CDialog::OnLButtonDown(nFlags, point);
}
#13
接收端代码:
void CFiveDlg::OnAcceptMessage(WPARAM wParam,LPARAM lParam)
{
int j;
sendinfo info;
gameinfo game_info;
CString m_Msg,m_name;
CEdit * output=NULL;
switch(lParam)
{
case FD_READ:
if(m_connection==wParam)
{
if(SOCKET_ERROR!=recv(m_connection,(char*)&info,sizeof(info),0))
{
if(info.cmd==2)
{
switch(info.type)
{
case 0: //当为0,表示用户进入
{
m_name=info.name;
m_Msg=m_name+"进入了游戏房间!\r\n";
//储存客户端的玩家信息
playerinfo[1].score=0;
playerinfo[1].m_win=0;
playerinfo[1].m_lost=0;
memcpy(playerinfo[1].grade,"菜鸟",20);
memcpy(playerinfo[1].name,m_name,m_name.GetLength()+1);
//发送所有玩家信息到新客户端
for(j=0;j<2;j++)
{
if(strcmp(playerinfo[j].name,""))
{
sendinfo infolist;
infolist.m_info=playerinfo[j];
infolist.type=0;
infolist.cmd=2;
memcpy(infolist.msg,"",100);
if(SOCKET_ERROR==send(m_connection,(char*)&infolist,
sizeof(infolist),0))
{
MessageBox("发送数据失败!");
return;
}
}
}
//当玩家进入时更新服务器信息
SetDlgItemText(IDC_TEXT2,m_name);
GetDlgItem(IDC_START)->EnableWindow(true);
m_sShowText=m_sShowText+m_Msg;
UpdateData(false);
CEdit * output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
//主机加所有玩家入列表
m_list1.DeleteAllItems();
index=-1;
for(j=0;j<2;j++)
{
if(strcmp(playerinfo[j].name,""))
{
InsertList(index,playerinfo[j]);
}
}
}
break;
case 1://当为1, 表示和大家聊天
m_sShowText=m_sShowText+info.msg;
UpdateData(false);
output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
break;
case 3://当为3、游戏结束后刷新玩家列表信息
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=info.m_info.name);j++);
UpdateList(info.m_info,j);
break;
}//end switch
}//end if
else
{
chessboard m_chessboard;
CString text1,text2;
game_info=*((gameinfo*)&info);
switch(game_info.type)
{
case 1://开始信息
m_WhiteOver=false;
m_BlackOver=false;
m_turn=game_info.m_turn;
text2=playerinfo[1].name;
if(game_info.m_turn==2)
{
text1=m_username+"\r\n"+"\r\n"+"黑方";
text2=text2+"\r\n"+"\r\n"+"白方";
}
if(game_info.m_turn==1)
{
text1=m_username+"\r\n"+"\r\n"+"白方";
text2=text2+"\r\n"+"\r\n"+"黑方";
}
GetDlgItem(IDC_TEXT1)->SetWindowText(text1);
GetDlgItem(IDC_TEXT2)->SetWindowText(text2);
m_match.Clear();
InvalidateRect(&m_rect,false);
break;
case 2://表示为游戏中棋子信息。
if(m_match.CanDown(game_info.m_x,game_info.m_y,game_info.m_turn))
{
m_chessboard.x=game_info.m_x;
m_chessboard.y=game_info.m_y;
m_chessboardlist.AddTail(m_chessboard);
OnPaint();
m_Myturn=game_info.m_turn%2+1;
}
break;
case 3://表示为游戏结束信息.
if(game_info.m_win==1)
m_WhiteOver=true;
if(game_info.m_win==2)
m_BlackOver=true;
SetDlgItemText(IDC_TEXT1,m_username);
SetDlgItemText(IDC_TEXT2,playerinfo[1].name);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
InvalidateRect(&m_rect,false);
m_Myturn=2;
m_bStart=false;
m_bReady=false;
break;
case 4://表示被动方通知主动方已经连接好
m_bReady=true;
break;
case 5:
{
chessboard m_chessboard;
if(m_chessboardlist.GetCount()<2)
return;
//刷新本方
for(int i=0;i<2;i++)
{
POSITION pos=m_chessboardlist.GetTailPosition();
m_chessboard=m_chessboardlist.GetAt(pos);
m_match.chessboard[m_chessboard.x][m_chessboard.y]=0;
m_chessboardlist.RemoveTail();
game_info.cmd=1;
game_info.type=5;
game_info.m_x=m_chessboard.x;
game_info.m_y=m_chessboard.y;
send(m_connection,(char*)&game_info,sizeof(game_info),0);
Sleep(10);
}
InvalidateRect(&m_rect,false);
break;
}
}//end switch
}//end else
return;
}//end if
}//end if
break;
case FD_CLOSE:
closesocket(m_connection);
m_connection=INVALID_SOCKET;
CString str,name;
name=playerinfo[1].name;
str=name+"离开游戏房间!\r\n";
memcpy(playerinfo[1].name,"",20);
//服务器更新数据
m_sShowText=m_sShowText+str;
for(int j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=name);j++);
m_list1.DeleteItem(j);
UpdateData(false);
index--;
m_match.Clear();
InvalidateRect(&m_rect,false);
SetDlgItemText(IDC_TEXT2,"");
SetDlgItemText(IDC_TEXT1,m_username);
GetDlgItem(IDC_START)->EnableWindow(false);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
CEdit * output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
break;
}//end switch
}
void CFiveDlg::OnAcceptMessage(WPARAM wParam,LPARAM lParam)
{
int j;
sendinfo info;
gameinfo game_info;
CString m_Msg,m_name;
CEdit * output=NULL;
switch(lParam)
{
case FD_READ:
if(m_connection==wParam)
{
if(SOCKET_ERROR!=recv(m_connection,(char*)&info,sizeof(info),0))
{
if(info.cmd==2)
{
switch(info.type)
{
case 0: //当为0,表示用户进入
{
m_name=info.name;
m_Msg=m_name+"进入了游戏房间!\r\n";
//储存客户端的玩家信息
playerinfo[1].score=0;
playerinfo[1].m_win=0;
playerinfo[1].m_lost=0;
memcpy(playerinfo[1].grade,"菜鸟",20);
memcpy(playerinfo[1].name,m_name,m_name.GetLength()+1);
//发送所有玩家信息到新客户端
for(j=0;j<2;j++)
{
if(strcmp(playerinfo[j].name,""))
{
sendinfo infolist;
infolist.m_info=playerinfo[j];
infolist.type=0;
infolist.cmd=2;
memcpy(infolist.msg,"",100);
if(SOCKET_ERROR==send(m_connection,(char*)&infolist,
sizeof(infolist),0))
{
MessageBox("发送数据失败!");
return;
}
}
}
//当玩家进入时更新服务器信息
SetDlgItemText(IDC_TEXT2,m_name);
GetDlgItem(IDC_START)->EnableWindow(true);
m_sShowText=m_sShowText+m_Msg;
UpdateData(false);
CEdit * output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
//主机加所有玩家入列表
m_list1.DeleteAllItems();
index=-1;
for(j=0;j<2;j++)
{
if(strcmp(playerinfo[j].name,""))
{
InsertList(index,playerinfo[j]);
}
}
}
break;
case 1://当为1, 表示和大家聊天
m_sShowText=m_sShowText+info.msg;
UpdateData(false);
output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
break;
case 3://当为3、游戏结束后刷新玩家列表信息
for(j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=info.m_info.name);j++);
UpdateList(info.m_info,j);
break;
}//end switch
}//end if
else
{
chessboard m_chessboard;
CString text1,text2;
game_info=*((gameinfo*)&info);
switch(game_info.type)
{
case 1://开始信息
m_WhiteOver=false;
m_BlackOver=false;
m_turn=game_info.m_turn;
text2=playerinfo[1].name;
if(game_info.m_turn==2)
{
text1=m_username+"\r\n"+"\r\n"+"黑方";
text2=text2+"\r\n"+"\r\n"+"白方";
}
if(game_info.m_turn==1)
{
text1=m_username+"\r\n"+"\r\n"+"白方";
text2=text2+"\r\n"+"\r\n"+"黑方";
}
GetDlgItem(IDC_TEXT1)->SetWindowText(text1);
GetDlgItem(IDC_TEXT2)->SetWindowText(text2);
m_match.Clear();
InvalidateRect(&m_rect,false);
break;
case 2://表示为游戏中棋子信息。
if(m_match.CanDown(game_info.m_x,game_info.m_y,game_info.m_turn))
{
m_chessboard.x=game_info.m_x;
m_chessboard.y=game_info.m_y;
m_chessboardlist.AddTail(m_chessboard);
OnPaint();
m_Myturn=game_info.m_turn%2+1;
}
break;
case 3://表示为游戏结束信息.
if(game_info.m_win==1)
m_WhiteOver=true;
if(game_info.m_win==2)
m_BlackOver=true;
SetDlgItemText(IDC_TEXT1,m_username);
SetDlgItemText(IDC_TEXT2,playerinfo[1].name);
GetDlgItem(IDC_START)->EnableWindow(true);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
InvalidateRect(&m_rect,false);
m_Myturn=2;
m_bStart=false;
m_bReady=false;
break;
case 4://表示被动方通知主动方已经连接好
m_bReady=true;
break;
case 5:
{
chessboard m_chessboard;
if(m_chessboardlist.GetCount()<2)
return;
//刷新本方
for(int i=0;i<2;i++)
{
POSITION pos=m_chessboardlist.GetTailPosition();
m_chessboard=m_chessboardlist.GetAt(pos);
m_match.chessboard[m_chessboard.x][m_chessboard.y]=0;
m_chessboardlist.RemoveTail();
game_info.cmd=1;
game_info.type=5;
game_info.m_x=m_chessboard.x;
game_info.m_y=m_chessboard.y;
send(m_connection,(char*)&game_info,sizeof(game_info),0);
Sleep(10);
}
InvalidateRect(&m_rect,false);
break;
}
}//end switch
}//end else
return;
}//end if
}//end if
break;
case FD_CLOSE:
closesocket(m_connection);
m_connection=INVALID_SOCKET;
CString str,name;
name=playerinfo[1].name;
str=name+"离开游戏房间!\r\n";
memcpy(playerinfo[1].name,"",20);
//服务器更新数据
m_sShowText=m_sShowText+str;
for(int j=0;j<m_list1.GetItemCount()&&(m_list1.GetItemText(j,0)!=name);j++);
m_list1.DeleteItem(j);
UpdateData(false);
index--;
m_match.Clear();
InvalidateRect(&m_rect,false);
SetDlgItemText(IDC_TEXT2,"");
SetDlgItemText(IDC_TEXT1,m_username);
GetDlgItem(IDC_START)->EnableWindow(false);
GetDlgItem(IDR_REGERT)->EnableWindow(false);
GetDlgItem(IDC_LOST)->EnableWindow(false);
CEdit * output=(CEdit*)GetDlgItem(IDC_SHOWTEXT);
output->LineScroll(output->GetLineCount());
break;
}//end switch
}
#14
代码太长了,不好意思。
#15
晕,代码太长,没仔细看。
一次send对应一次recv,成功接收到一次send,recv就自动返回了,如果在同一函数内对内一接收方send两次,那对方同样需要同一函数内recv两次
我数了一下,你好像send了两次,而之recv了一次,那另一次send的东西由谁来接收呢?
一次send对应一次recv,成功接收到一次send,recv就自动返回了,如果在同一函数内对内一接收方send两次,那对方同样需要同一函数内recv两次
我数了一下,你好像send了两次,而之recv了一次,那另一次send的东西由谁来接收呢?
#16
另外,好像你的send和recv都是在主线程里干的,而且你用的好像是阻塞方式了,主程是不是经常就这样锁住了,莫非阁下在做五子棋什么的小游戏。。。?
#17
我用的异步选择方式啊,在做个五子棋
#18
FD_READ 我是先接过来,再去判断可以吗?
#19
还在吗?
#20
调用两次OnAcceptMessage()
你的函数一次OnAcceptMessage()只接收一次Socket信息,发送方每发送一次信息,这边都要调用一次OnAcceptMessage();
其实这个问题在MFC框架中是不存在的,可以在OnReceive()中调用,MFC会每接收一次信息即调用一次OnReceive(),但是你自己处理的过程就不同了。
你的函数一次OnAcceptMessage()只接收一次Socket信息,发送方每发送一次信息,这边都要调用一次OnAcceptMessage();
其实这个问题在MFC框架中是不存在的,可以在OnReceive()中调用,MFC会每接收一次信息即调用一次OnReceive(),但是你自己处理的过程就不同了。
#21
up
#22
我用API写的
#23
#24
狂晕
#25
你的CODE里面的send有点问题 ,unblocking模式有可能导致你在还未完全收到Message之前,就已经返回。mybe, who could got it really?
#26
那应该如何解决呢?我用线程控制住发送端可以吗?
#27
继续关注中,我用Sleep函数加在send函数之间,可以解决问题,可是这样等待时间太长了
#28
还是用blocking模式比较好,send和recv放在独立的线程中。
或者改用mfc的CAsyncSock,异步方式利用里面的事件做处理方便多了。
或者改用mfc的CAsyncSock,异步方式利用里面的事件做处理方便多了。