基于TCP的MFC程序编写 connect可以连接 服务器端的send函数报错

基于TCP的MFC程序编写 connect可以连接 服务器端的send函数出错
编程平台VS2013
首先是服务器端的代码
ChatDlg.h中的部分代码如下:
class CChatDlg : public CDialogEx
{
// 构造
.........................
// 对话框数据
.........................
// 实现
protected:
HICON m_hIcon;

// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnSock(WPARAM, LPARAM);   //用于异步通信的消息响应函数
DECLARE_MESSAGE_MAP()
private:
SOCKET m_socket;                //m_socket用于收听
SOCKET m_socketApt;             //m_socketApt用于接收
SOCKADDR_IN addrFrom; //用于接收客户端的地址
int len = sizeof(SOCKADDR);
public:
BOOL InitSocket();

afx_msg void OnBtnSend();
};

InitSocket()代码如下:
BOOL CChatDlg::InitSocket()
{
m_socket = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, 0);
if (INVALID_SOCKET == m_socket)
{
MessageBox("创建套接字失败!");
return FALSE;
}
SOCKADDR_IN addrSock;
addrSock.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSock.sin_family = AF_INET;
addrSock.sin_port = htons(758);
if (SOCKET_ERROR == bind(m_socket, (SOCKADDR*)&addrSock, sizeof(SOCKADDR)))
{
MessageBox("绑定失败!");
return FALSE;
}
::listen(m_socket, 2);
if (SOCKET_ERROR == WSAAsyncSelect(m_socket, m_hWnd, UM_SOCK, FD_READ))
{
MessageBox("注册网络读取事件失败!");
return FALSE;
}

m_socketApt = accept(m_socket, (SOCKADDR*)&addrFrom, &len);
return TRUE;
}

然后在CChatDlg::OnInitDialog()函数中调用InitSocket

CChatDlg::OnBtnSend函数的代码如下,和发送按钮相关联

void CChatDlg::OnBtnSend
{
CString str = "";
GetDlgItem(IDC_EDIT_SEND)->GetWindowText(str);
if (str == "")
{
MessageBox("消息不能为空!");
}
else
{
if (::send(m_socketApt, str.GetBuffer(1), sizeof(str), 0) != SOCKET_ERROR)
{
GetDlgItem(IDC_EDIT_SEND)->SetWindowText("消息已经发送到客户端!\r\n");
str += "\r\n";
GetDlgItem(IDC_EDIT_SEND)->SetWindowText(str);
}
else
{
GetDlgItem(IDC_EDIT_SEND)->SetWindowText("消息发送失败!\r\n");
}
}
}


服务器的界面如下图所示:
基于TCP的MFC程序编写 connect可以连接 服务器端的send函数报错

客户端代码:
class CChatDlg : public CDialogEx
{
// 构造
public:
CChatDlg(CWnd* pParent = NULL); // 标准构造函数
~CChatDlg()
{
if (m_socket)
closesocket(m_socket);
}
// 对话框数据
enum { IDD = IDD_CHAT_DIALOG };

protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持


// 实现
protected:
HICON m_hIcon;

// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LRESULT OnSock(WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
private:
SOCKET m_socket;
public:
BOOL InitSocket();

afx_msg void OnBtnSend();

afx_msg void OnConnect();
};


客户端的OnBtnSend函数如下所示:
void CChatDlg::OnBtnSend()
{
CString str = "";
GetDlgItem(IDC_EDIT_SEND)->GetWindowText(str);
if (str == "")
{
MessageBox("消息不能为空!");
}
else
{
if (::send(m_socketApt, str.GetBuffer(1), sizeof(str), 0) != SOCKET_ERROR)
{
GetDlgItem(IDC_EDIT_SEND)->SetWindowText("消息已经发送到客户端!\r\n");
str += "\r\n";
GetDlgItem(IDC_EDIT_SEND)->SetWindowText(str);
}
else
{
GetDlgItem(IDC_EDIT_SEND)->SetWindowText("消息发送失败!\r\n");
}
}
}

客户端的界面如下:
基于TCP的MFC程序编写 connect可以连接 服务器端的send函数报错

可以连接成功,但是当电极服务器端的发送键时,总是显示消息发送失败,如图所示:
服务器端的图片为:
基于TCP的MFC程序编写 connect可以连接 服务器端的send函数报错

客户端的图片为:
基于TCP的MFC程序编写 connect可以连接 服务器端的send函数报错

------解决方案--------------------
查看send失败时的错误信息
------解决方案--------------------
单步调试查看m_socketApt是否有效,调用WSAGetLastError获取更多的错误信息
GetBuffer意义不明,CString不能用sizeof得到长度

------解决方案--------------------
m_socket = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, 0);
其中SOCK_DGRAM使用的是UDP协议,而不是TCP协议,收发命令是否该用Readfrom,Sendto;
------解决方案--------------------
WSAGetLastError()要紧接着WSASend之后第一个被调用