昨天花了点时间,写了个小程序,做了个局域网内的文件传输工具。当然了,关键在于学习,局域网内的文件用共享就好了,还有什么好传的。但里面用到的知识是可以用在INTERNET上的,只不过如果用在公网上的话一般还需要一个服务器的中转,多一步NAT穿透技术的支持。就是在做这个小程序的时候也出现过一些问题。先把关键部分代码贴出,再细细解释。
这是我用于传输文件信息的结构体,本来我将buf定义为CString类型,在传送阶段没有出现错误,很正常,但是在接收端却出现了异常,接收端接收到的buf显示的是乱码,至今不知道为什么。
这是发送端代码,因为要询问对方是否同意接收,所以要多了一个线程用于等待对方消息。如果没有多增加一个线程的话,等待将是痛苦的,而如果是在本机上进行测试的话,这样的等待更将是没有结果的,因为你根本没有表达的机会,就在那“死循环”。
这就是那个专门用于等待对方应答和发送文件正文的线程。做这个的过程中不得不提的就是通过int WSAGetLastError (void);函数得到的发送错误报警10038,在CSDN当中,查到的10038提示的错误是:
WSAENOTSOCK-
Socket operation on nonsocket.
- An operation was attempted on something that is not a socket. Either the socket handle parameter did not reference a valid socket, or for select, a member of an fd_set was not valid.
说的大概意思就是在一个无效的SOCKET上进行操作。我出现这个错误的原因并不是因为SOCKET关闭或者SOCKET的什么问题,而是因为当中的一个变量——用于表示文件路径名的FilePath定义得过小,这可能就导致了该说明所提到的第二个错误 for select, a member of an fd_set was not valid。
这是接收端的代码之一,我使用的是异步套接字进行接收,感觉挺方便的。当然,接收端跟发送端一样,也需要在建立一个线程,用于回答发送端的询问。如果没有多一个线程的话,等待也将是痛苦的。
这就是接收端新增加的线程。
当中还定义了几个自定义消息和静态成员变量。之所以定义静态成员变量是因为CreateThread函数的响应函数是一个静态成员函数,要在外部对工作在它内部的一个变量进行修改,方法之一就是定义一个静态成员变量。但是需要记住的一点就是静态成员变量的初始化必须在类的外部。
大概的程序就是如此,不足还有很多,希望路过者多提宝贵意见,共同学习,共同进步。