我要在客户端每隔30秒向服务器端发送数据,采用TCP/IP协议,协议格式已经定好了。我自己封装了一个SOCKET类CMySocket,在这个类里将SOCKET的一些API函数重新封装了一下。
class CMySocket
{
SOCKET m_socket;
void InitSocket(); //加载库并创建SOCKET实例m_socket
BOOL ConnectServ(); //连接服务器
void SendData(char *,int nLength); //发送数据
void RecvData(char *,int nLength); //接收数据
}
然后我在主线程对话框类头文件里定义了一个CMySocket对象m_sockClient。为了防止主线程阻塞,我想采用多线程的办法。在对话框的OnInitDialog()函数里用AfxBeginThread创建一个工作线程。
BOOL CTestClientDlg::OnInitDialog()
{
...
m_sockClient.InitSocket();
AfxBeginThread(ConnectThread,); /// ??
}我有几个疑问:1. 在线程之间传递MFC对象和SOCKET对象不安全,只能选择传递句柄。那我怎么将m_sockClient对象传递给线程函数?要是传递句柄的话那我岂不是没办法调用CMySocket对象的成员函数了。2. 我是在在ConnectServ()函数里调用connect函数连接的服务器端,因为我要周期性的发送数据给服务器,为保证始终都处于连接状态,那我在一个while死循环调用connect函数是否可行?3. 当我在SendData(char *,int nLength)函数里调用send函数向服务器发送数据时,我如何知道当前与服务器是处在连接状态,还是断掉?怎么得到这一信息?4. 我要周期性的发送数据,那是不是只要周期性的调用send函数就可以了?5. 当我按照指定的协议格式将数据发送过去后,是不是一定能保证数据准确被接收?万一不能被准确接收,我该怎么操作才能保证传输过去的数据不会出错?本人刚刚开始接触TCP网络编程,所以可能问的问题有点多,也很菜:),希望大家不吝赐教,在此致谢。
class CMySocket
{
SOCKET m_socket;
void InitSocket(); //加载库并创建SOCKET实例m_socket
BOOL ConnectServ(); //连接服务器
void SendData(char *,int nLength); //发送数据
void RecvData(char *,int nLength); //接收数据
}
然后我在主线程对话框类头文件里定义了一个CMySocket对象m_sockClient。为了防止主线程阻塞,我想采用多线程的办法。在对话框的OnInitDialog()函数里用AfxBeginThread创建一个工作线程。
BOOL CTestClientDlg::OnInitDialog()
{
...
m_sockClient.InitSocket();
AfxBeginThread(ConnectThread,); /// ??
}我有几个疑问:1. 在线程之间传递MFC对象和SOCKET对象不安全,只能选择传递句柄。那我怎么将m_sockClient对象传递给线程函数?要是传递句柄的话那我岂不是没办法调用CMySocket对象的成员函数了。2. 我是在在ConnectServ()函数里调用connect函数连接的服务器端,因为我要周期性的发送数据给服务器,为保证始终都处于连接状态,那我在一个while死循环调用connect函数是否可行?3. 当我在SendData(char *,int nLength)函数里调用send函数向服务器发送数据时,我如何知道当前与服务器是处在连接状态,还是断掉?怎么得到这一信息?4. 我要周期性的发送数据,那是不是只要周期性的调用send函数就可以了?5. 当我按照指定的协议格式将数据发送过去后,是不是一定能保证数据准确被接收?万一不能被准确接收,我该怎么操作才能保证传输过去的数据不会出错?本人刚刚开始接触TCP网络编程,所以可能问的问题有点多,也很菜:),希望大家不吝赐教,在此致谢。
解决方案 »
- 求助:CStatic上画曲线,单击曲线显示坐标
- listctrl的鼠标滚轮响应?
- 如何让ACCESS中的数据进行加法/减法运算
- InstallShield 制作安装完成后启动程序功能??
- *******HTML中为什么无法调用ActiveX控件?????在线等待!
- 如何在另一个进程中显示对话框?
- CSocket在使用静态连接库下出现问题。着急!!!在线
- 请问后缀为wdl的文件用什么软件阅读?
- 硬盘的C区读不出来,下载了easyRecovery来恢复却不好用,还有啥好方法或好软件,请帮忙提供一下下载网址或软件名供搜索用
- 高手看过来~!!!! 这是很有难度的问题啊~~~~~~~~~~!!!!
- 简单的WinSocket编程时,如何实现程序既可以接收数据,又可以发送数据?
- 散分散分
2、是否用死循环完全是个人爱好,不过最好能够再加一些错误判断和处理。
3、如果Send返回错误,根据错误码可以判断。
4、在不出错的情况下是这样。
5、Send返回成功就表示数据已经被准确接收,如果Send返回失败,则要根据错误码来判断问题,并决定是否重新连接。
2-4.可以设置一个时钟,在时钟函数里ConnectServ(),连接成功后再SendData。
5.Send只能表示数据被成功发送,并不能保证在接受端数据被准确接受。一定能保证数据准确被接收
----------------------------
这个有点复杂了,其实在你的程序中也可以做,有三次握手规则。
你可以将 ConnectThread 当作 CTestClientDlg 类的成员函数,启动线程的时候直接将this传给它,但由于ConnectThread 是一个静态函数,你需要一个辅助函数才行,可以用this来调用:
unsigned int CTestClientDlg::ConnectThread(void *param)
{
CTestClientDlg *pThis = (CTestClientDlg *)param;
return pThis->ConnectThreadFunction(); // 这样你就能直接访问类中的成员了
}2. 我是在在ConnectServ()函数里调用connect函数连接的服务器端,因为我要周期性的发送数据给服务器,为保证始终都处于连接状态,那我在一个while死循环调用connect函数是否可行?
你为什么要反复的调用connect函数?如果是短连接的话,用udp不是更合适吗?
3. 当我在SendData(char *,int nLength)函数里调用send函数向服务器发送数据时,我如何知道当前与服务器是处在连接状态,还是断掉?怎么得到这一信息?
根据send的返回值,socket_error表示出错。4. 我要周期性的发送数据,那是不是只要周期性的调用send函数就可以了?
可以用一个timer或是启动一个线程5. 当我按照指定的协议格式将数据发送过去后,是不是一定能保证数据准确被接收?万一不能被准确接收,我该怎么操作才能保证传输过去的数据不会出错?
tcp/ip 属于稳定传输,只要能发送成功,就能保证正确接收。为了更加保险起见,服务端收到数据后应该给客户端回一条确认消息
你可以将m_sockClient的指针传过去。如果你自己封装的Socket与线程无关传递对象也可以。2. 我是在在ConnectServ()函数里调用connect函数连接的服务器端,因为我要周期性的发送数据给服务器,为保证始终都处于连接状态,那我在一个while死循环调用connect函数是否可行?
如果始终都处于连接状态你就没有必要一直connect服务器了。你只需要周期性的判断一下服务器是否关闭就行了。如果你的connect每次都返回一个新的socket是不是比较浪费?3. 当我在SendData(char *,int nLength)函数里调用send函数向服务器发送数据时,我如何知道当前与服务器是处在连接状态,还是断掉?怎么得到这一信息?
send函数的返回值,看看getlasterror就知道了。4. 我要周期性的发送数据,那是不是只要周期性的调用send函数就可以了?
一次connect,周期性的使用connect返回的socket去send数据就可以了。如果你是带界面的程序用timer可以,如果是控制台程序你就得自己dispatch消息。5. 当我按照指定的协议格式将数据发送过去后,是不是一定能保证数据准确被接收?万一不能被准确接收,我该怎么操作才能保证传输过去的数据不会出错?
你可以使用CRC校验一下你发送与接收的数据是否正确。如果接收正确可以返回一个类似ACK的信息。如果传过去的数据不正确你可以根据返回的信息决定是否重新发送。6、异步socket处理起来相对麻烦一些。如果你需要定期去connect连接远程服务器,调用connect函数时如果服务器关闭或你连接的ip不正确阻塞模式的socket会有一段等时间,最长应该是75秒。这时候你可以选用异步socket来connect使用select来确定是否连接成功。当连接成功时你可以再设为阻塞方式来处理。