关于SOCKET通信遇到的问题小结

最近在做点通信方面的东西。由于好久不碰C了,还真遇到了几个坑爹的问题。全是我自己犯的低级错误,把它记下来。防止忘记。

1. 对于数据接收recvfrom操作设置为阻塞模式无效
我需要在阻塞模式下进行数据传输,同时设定超时机制。但问题是我通过setsockopt一级ioctlsocket,既无法阻塞,更不用测试超时的问题了。但是就那几行代码,怎么翻来覆去的都感觉没有问题。无奈之下看MSDN得例子,发现有一个小问题,测试之下,果然是这个问题。

错误代码如下:

int sockfd = ::socket(AF_INET, SOCK_DGRAM, 0);

.........................
setsockopt(....);
ioctlsocket(.....);

struct sockaddr_in peer;
int len;
char* buf = (char*)malloc(BLK_SIZE);
recvfrom(sockfd, buf, BLK_SIZE, 0, (struct sockaddr*)&peer, &len);

.......................
这段代码不管怎么执行,在recvfrom这个地方都是直接返回-1. 后来通过WSAGetLastError函数查看错误码,
错误值为:10014,官方解释为:WSAEFAULT

Bad Address.
The system detected an invalid pointer address in attempting to use a pointer argument of call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small.For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).
结合错误解释以及官方实例,一看就明白了。是我的参数len没有初始化。
int len = sizeof(struct sockaddr_in); 最后一个参数len,应该正确描述地址结构体的长度!

就OK了。

2. 文件传输的过程中,传输前和传输后不一样

采用的测试方法:
定义了一个简单的checksum函数,即校验函数。对传输前以及传输后的内存块计算一个校验值。来判断是否数据一致,同时利用UltraEdit做二进制比较。但是发现每次传输的内存块前后校验值是一样的。但是写入文件后就
不一样了。百思不得其解。后来想起来,文件都跟写的方式应该一致!!!

在读的时候采用"rb"模式,即二进制只读模式
在写的时候采用"w"模式,而在默认情况下,是按照文本模式写的。所以改为"wb"模式,即可。


这只是两个小问题,平时写起来的时候觉得很简单。但是这次却在小问题上花了些时间。细节问题没有考虑
到位。

你可能感兴趣的:(socket,recvfrom,文件处理)