winsock2 图片传输

本文详细介绍了图片传输的基本步骤及使用WinSock进行图片传输的具体实现方法,包括客户端和服务端的操作流程,并深入解析了WinSock中关键函数的使用。

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

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

第二部:客户端通过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句柄实现的。

 

服务器端:

绑定、监听、接受连接

 

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

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

 

 

 

 

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


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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值