以下是引用laibinhua在2019-9-24 14:16:30的发言:
原因找到了,其实是SOCKET 客户端发过来的字符超过8K时自动拆分成多个包了,SOCKET服务端分批收取了数据,只是不知道如何拼包合并包,老师有什么办法合并包吗?
好多时每次 send 是不等于 recv 的。
不好意思,没用winsock组件。通常传送数据用TCP协议的多,可以参考相关TCP/IP协议发送与接收方面的资料。
以传送文件简单说一下,用C语言来表达,VFP调用winsock API来写也可以。
//发送端
//循环发送数据,直到文件结尾
char buffer[BUF_SIZE] = {0};
//缓冲区
int nCount;
while ((nCount = fread(buffer, 1, BUF_SIZE, fp)) > 0 )
{
send(clntSock, buffer, nCount, 0);
}
shutdown(clntSock, SD_SEND);
//文件读取完毕,断开输出流,向客户端发送FIN包
recv(clntSock, buffer, BUF_SIZE, 0);
//阻塞,等待客户端接收完毕
fclose(fp);
closesocket(clntSock);
closesocket(servSock);
WSACleanup();
//接收端
//循环接收接收,直到文件传输完毕
char buffer[BUF_SIZE] = {0}; //文件缓冲区
int nCount;
while ((nCount = recv(sock, buffer, BUF_SIZE, 0)) > 0 )
{
fwrite(buffer, nCount, 1, fp);
}
fclose(fp);
closesocket(sock);
WSACleanup();
问题重点理解几点:
close()、closesocket()、shutdown() 和 FIN 包
close() 和 closesocket() 用来关闭套接字,之后不能使用该套接字。关闭套接字后,与该套接字相关的连接和缓存也失效。
shutdown() 用来关闭连接,而不关闭套接字。
调用 close()、closesocket() 关闭套接字,或调用 shutdown() 关闭输出流时,都会向对方发送 FIN 包。
FIN 包表示数据传输完毕,计算机收到 FIN 包就知道不会再有数据传送过来了。
默认情况下 close()、closesocket() 会立即发送FIN包,不管输出缓冲区中是否还有数据,而shutdown() 会等输出缓冲区中的数据传输完毕再发送FIN包。也就意味着,调用 close()、closesocket() 将丢失输出缓冲区中的数据,而调用 shutdown() 不会。
[此贴子已经被作者于2019-9-25 06:21编辑过]