winsock2 图片传输

来源:互联网 发布:模拟科目二练车软件 编辑:程序博客网 时间:2024/06/04 18:21

最近项目需要进行图片传输,以前只做过字符串的通信,其实图片和字符串差不多,只是开头多了一个解析的过程,

第一步:客户端发送指令给服务端,告诉服务端图片来了

第二部:客户端通过fread(*fp,size)    读取图片循环多次发送。

第三步:服务端通过fwrite(*fp,size)  将读取的信息逐步写入文件,写入后记得移动文件指针到文件尾

              fseek(File*fp, int offset, int origin);

                   origin:0表示文件头、1表示当前位置、2表示文件尾

 

第四部:服务器端循环读取,当读取信息=0;表示读取完毕,这是保存图片即可。

 

下面再简单介绍下winsock中的方法(以下方法都摘自winsock.h头文件):

 

Socket在通信之前需要知道彼此的地址,一般这个地址由IP和PORT决定

在winsock中使用SOCKADDR_IN来指定地址信息     

下面简单介绍下sockaddr和sockaddr_in这两个结构体的介绍,这两个结构体在ws2def.h中定义

//// IPv4 Socket address, Internet style// typedef struct sockaddr_in {  #if(_WIN32_WINNT < 0x0600)    short  sin_family;#else //(_WIN32_WINNT < 0x0600)    ADDRESS_FAMILY sin_family;       //一般该字段设置为AF_INET,表示winsock此时正在使用IP地址族。地址家族,一般以AF_XXXX开头#endif //(_WIN32_WINNT < 0x0600) USHORT sin_port;//将地址作为一个4字节的量存储(IP4) // sin_addr.s_addr= inet_addr(“192.168.0.1”)  存储IPv4的内容IN_ADDR sin_addr;                                                CHAR sin_zero[8];    //只充当填充项、使SOCKADDR_IN和SOCKADDR结构长度一致} SOCKADDR_IN, *PSOCKADDR_IN;

这个数据结构主要用在bind、connect、recvfrom、sendto等函数中,指明地址信息


//// IPv4 Internet address// This is an 'on-wire' format structure.//typedef struct in_addr {union {struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { USHORT s_w1,s_w2; } S_un_w;ULONG S_addr;        } S_un;#define s_addr S_un.S_addr /* can be used for most tcp & ip code */#define s_host S_un.S_un_b.s_b2    // host on imp#define s_net  S_un.S_un_b.s_b1    // network#define s_imp  S_un.S_un_w.s_w2    // imp#define s_impno S_un.S_un_b.s_b4    // imp ##define s_lh   S_un.S_un_b.s_b3    // logical host} IN_ADDR, *PIN_ADDR,FAR *LPIN_ADDR;  //// Structure used to store most addresses.//typedef struct sockaddr { #if (_WIN32_WINNT < 0x0600)    u_short sa_family;#else    ADDRESS_FAMILY sa_family;          // Address family.  ADDRESS_FAMILY就是unsigned short#endif //(_WIN32_WINNT < 0x0600)     CHAR sa_data[14];                  // Up to 14 bytes of direct address.} SOCKADDR, *PSOCKADDR,FAR *LPSOCKADDR;

 

Socket套接字:

 套接字是通信时提供的句柄,在winsock中的操作都是基于套接字实现的。在winsock中实现套接字有两种方法:

Socket和WSASocket:

SOCKET WINAPI socket(int af   // 协议地址族;一般为AF_INET

Int type //  TCP/IP是SOCK_STREAM

// UDP/IP 是SOCK_DGRAM

Int protocol    //协议标准 

TCP IPROTO_TCP

IPPROTO_UDP)

 

如果创建成功,则会返回一个有效的SOCKET句柄;

后续的bind、listen、connect、send、recv都是基于该SOCKET句柄实现的。

 

服务器端:

绑定、监听、接受连接

 

intWSAAPIbind(    _In_ SOCKET s,     //要绑定的socket    _In_reads_bytes_(namelen)const struct sockaddr FAR * name,  //指定要进行绑定的地址结构,即SOCKADDRE_IN结构    _In_ int namelen      //参数二的长度    );  intWSAAPIlisten(    _In_ SOCKET s,     //要监听的socket    _In_ int backlog     //监听的最大数量,当超过该数量后,监听失败    );   SOCKETWSAAPIaccept(    _In_ SOCKET s,                         //处于监听模式的socket    _Out_writes_bytes_opt_(*addrlen)struct sockaddrFAR * addr,    //连接后的获得//对方的地址信息    _Inout_opt_ int FAR * addrlen       //参数二的结构体长度);

//当该函数调用成功后,会返回socket、然后通过该socket可以与客户端进行通信了

 

 

 

 

客户端:客户端在初始化一个SOCKET后,需要连接后才可以开始进行通信,这时必须调用connect函数;


intWSAAPIconnect(    _In_ SOCKET s,    _In_reads_bytes_(namelen)const struct sockaddr FAR * name,    _In_ int namelen   );


0 0