最近项目需要进行图片传输,以前只做过字符串的通信,其实图片和字符串差不多,只是开头多了一个解析的过程,
第一步:客户端发送指令给服务端,告诉服务端图片来了
第二部:客户端通过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
);
本文详细介绍了图片传输的基本步骤及使用WinSock进行图片传输的具体实现方法,包括客户端和服务端的操作流程,并深入解析了WinSock中关键函数的使用。
2729

被折叠的 条评论
为什么被折叠?



