各位达人:
我现在需要实现这样的一个功能,客户端发出请求,服务器端接受到请求后,就持续发送数据到客户端,客户端接受到数据后再进行处理。这里先不说客户端接收到数据后处理的问题。
就说发送和接收的问题。该如何实现呢!
我试验过如下两种方法。
第一、客户端发送一个请求,服务器接受到请求后,就不停地发送数据。然后客户端就不停地接受。什么时候,客户端不想要了,就发送一个停止发送的请求。
但我遇到的问题是:服务器在连续发送若干个数据块后,再发送数据,就会返回-1。但WSAGetLastError()却返回0。
第二、一问一答的方式,也就是,客户端发送一个请求,服务器接受到请求后,就回送一个数据块。然后客户端继续发送请求,服务器就再回送数据块。
这个方法遇到的问题是,客户端请求若干个数据块后,就接受不到数据了,为了调试,我在服务器端和客户端都写了调试输出信息,发现,客户端发送请求调用的send函数,返回值是正确的。并且服务器端也收到了这个请求,而且服务器也回送了指定大小的数据块,服务器回送数据块调用send返回值也确实是要发送的数据块的大小。但客户端就接收不到数据了,一直停在recv上。
我的环境:
win2003server+vc6.0(sp6),socket没有使用mfc里的。通信使用tcp方式。
我现在需要实现这样的一个功能,客户端发出请求,服务器端接受到请求后,就持续发送数据到客户端,客户端接受到数据后再进行处理。这里先不说客户端接收到数据后处理的问题。
就说发送和接收的问题。该如何实现呢!
我试验过如下两种方法。
第一、客户端发送一个请求,服务器接受到请求后,就不停地发送数据。然后客户端就不停地接受。什么时候,客户端不想要了,就发送一个停止发送的请求。
但我遇到的问题是:服务器在连续发送若干个数据块后,再发送数据,就会返回-1。但WSAGetLastError()却返回0。
第二、一问一答的方式,也就是,客户端发送一个请求,服务器接受到请求后,就回送一个数据块。然后客户端继续发送请求,服务器就再回送数据块。
这个方法遇到的问题是,客户端请求若干个数据块后,就接受不到数据了,为了调试,我在服务器端和客户端都写了调试输出信息,发现,客户端发送请求调用的send函数,返回值是正确的。并且服务器端也收到了这个请求,而且服务器也回送了指定大小的数据块,服务器回送数据块调用send返回值也确实是要发送的数据块的大小。但客户端就接收不到数据了,一直停在recv上。
我的环境:
win2003server+vc6.0(sp6),socket没有使用mfc里的。通信使用tcp方式。
解决方案 »
- GDI+画图重绘时窗口会闪烁的问题
- VC 定义两个菜单ID的值居然一样而没有报错,响应消息的时候出错???怎么解决?????????????
- 简单的字符串声明问题
- 怎么检测一个进程加载了哪些dll?
- 如何拦截窗口的最大化,最小化和关闭这些消息,以便加入自己的处理代码。
- 对于一个可广播的套接字,发送时用广播地址同指定ip地址有时么不同?有条件的朋友请试一下该程序!
- 请教高手:关于IE的右键菜单问题
- 分享串口操作类 希望高手能够解决多串口操作
- CHtmlView类的 OnNewWindow()函数是增加一新窗口吗?我怎么不会用?大侠能告诉我吗?
- Windows核心编程的源码编译问题,请高手指教
- stl map insert()操作后map中的地址和我要插入的地址不一致
- yuv422 如何转成 RGB24?
用非阻塞方式
WSAAsyncSelect(ServerSock, m_hWnd, NETWORK_EVENT, FD_ACCEPT | FD_CLOSE | FD_READ | FD_WRITE)
这个函数来实现吧。
那我的问题是,客户端还好说,因为客户端有窗口,当然就可以使用消息接收,也就有m_hWnd,但服务器端,我的程序是一个控制台程序,并且程序最总要最为服务来运行,怎么实现呢?现在程序写到这个份上了,不可能再改成使用CAsyncSocket了。
我现在用的是非MFC的socket,也就是自己调用socket函数来创建SOCKET。
给个建议吧。
能不能使用select函数,实现非阻塞呢。
还有,socket是阻塞模式,为什么会出现我遇到的那个情况呢?
难道阻塞模式就不能实现持续发送数据?
我改成异步处理接收到的数据再试验一下。
另外,还几个问题如下:
1、如果使用非阻塞模式,发送数据的时候,比如调用一次send发送10K(这只是我举的例子)数据,是否会出现只发送一部分的情况。我想要的结果最好是我让send发送10k,要是发送成功就因该完全发送出去,否则,就一个字节就别发送,直接返回-1。到底是哪种情况呢?
2、非阻塞模式下,接收数据的时候,如果我指定要求接受10K的数据,会不会出现接受到数据并没有10K,而是小于10K的数字。
我想,如果接收缓冲区里没有10K的数据可供接受,肯定返回的不会是10K,但如果接收缓冲区里有足够的数据呢?当然要想让接收缓冲区的数据足够,必须要在第一个问题上要按照我想要的那种方式发送。不知道是否是这样!
3、之所以我有1,2两个问题,是因为服务器端每次发送数据的数据,除了实际的数据体外,每次发送都要有一个数据头,实际上是一个结构,大约有18个字节,这个结构就是自己定义的协议。并且结构里有一个成员,是指明实际的数据长度。接受端必须先接受到这个结构,然后根据结构里的数据长度,来接受实际的数据。这样接受来得数据才是有意义的。
请指点一下!谢谢!
主要还是对socket的工作过程和原理不理解才造成了我现在这么多的问题。
我先把客户端接受数据按照异步处理的方法试验一下吧。
实在不行,只能是改成非阻塞模式了。
你既然有自定义了协议,接收线程接收数据完只管拷贝到数据队列里面,另外一个线程循环从数据队列里面读取最前面的数据头,取出长度,然后再读取指定长度后面的数据,如果长度不够,继续下一次循环。
unsigned char *buf[1000]; //缓冲区
unsigned int len=0; //缓冲区里里面数据长度假设你收到的数据是unsigned char *recvdata;长度是recvlen;收到数据后
memcpy(buf+len,recvdata,recvlen);
len+=recvlen;当然两个线程同时访问buf和len 所以需要做线程同步 设置个mutex就差不多了
我先吃饭 下午联系
那取出呢?
取走数据后,后面的数据是不是要往前挪呀。
能不能大致给我描述一下放数据和取数据对buf缓冲区的操作过程。
谢谢了
unsigned int len=0; //缓冲区里里面数据长度 放入数据:
假设你收到的数据是unsigned char *recvdata;长度是recvlen; memcpy(buf+len,recvdata,recvlen);
len+=recvlen; 另外一个线程取出数据:
比如数据最前面两个字节表示后面数据的长度 假设已经取出来叫datalenunsigned char *buf_temp=(unsigned char *)malloc(datalen);memcpy(buf_temp,buf,datalen); //取出来
memcpy(buf,buf+datalen,len-datalen); //后面数据往前面移
len-=datalen;由于取出放入数据线程都需要访问修改buf和len 因此要弄个互斥体来保护一下