MFC网络编程

最近这段时间,一直都在学习套接字编程,下面就写写自己学习的一些相关知识,也算是学习笔记吧(这篇文章主要参考孙鑫老师的教学视频和相关文档)。

首先是关于WinSocket网络编程方面的:

一、套接字的类型:

   主要有三类:1、流式套接字(SOCK_STREAM),主要提供面向连接、可靠地数据传输服务,数据能够无差错的无重复的发送,并且能够按顺序的进行接收,主要基于TCP协议实现的

                     2、数据报式套接字(SOCK_DGRAM),主要提供无连接的服务,数据包能够独立的进行发送,不提供无错保证,数据可能会丢失或者重复,并且接收的顺序比较混乱,这种类型主要基于UDP协议实现的,所以这种类型的即时性比较高。(聊天通讯软件一般都是采用这种形式实现的)

                     3、原始套接字(SOCK_RAW),这种套接字一定要在root下使用,可以接受到本机网卡上的数据帧或者数据包,对于监听网络的流量和分析是很有作用的。

 

二、基于TCP(面向连接)socket编程的程序编写流程:

1、服务器端程序流程

    a、创建套接字(socket)。

    b、将套接字绑定到一个本地地址和端口上(bind)。

    c、将套接字设为监听模式,准备接受客户请求(listen)。

    d、等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)

    e、用返回的套接字和客户端进行通信(send/recv)。

    f、返回,等待另一个客户请求。

    g、关闭套接字

 

2、客户端程序编写流程

    a、创建套接字(socket)。

    b、向服务器发出连接请求(connect)。

    c、和服务器端进行通信(send/recv)。

    d、关闭套接字。

 

 服务器端程序编写流程:

 1、创建套接字(socket).

SOCKET socket (
    int af, //指定的地址族,对于TCP/IP协议的套接字,他只能是AF_INET(也可以写成PF_INET)
    int type, //指定socket类型,对于1.1版本的socket,它支持两种类型的套接字,SOCK_STREAM指定产生流式套接字,SOCK_DGRAM指定产生数据报式套接字
    int protocol //是与特定的地址族相关的协议,如果指定为0,那么系统会根据地址格式和套接字类别,自动选择一个合适的协议(推荐这么使用)
); 

 2、将套接字绑定到一个本地地址和端口上(bind).

int bind(
    SOCKET s,  //要绑定的套接字                        
    const struct sockaddr FAR *name,   //指定了该套接字的本地地址信息,这是一个指向sockaddr结构的指针变量,由于该地址结构是为所有的地址家族准备的,这个结构通常会随使用的网络协议不同而不同  
    int namelen   //指定该地址结构的长度                    
);

a、sockaddr结构的定义如下(可以用sockaddr_in结构替换sockaddr,以方便我们填写地址信息):

struct sockaddr {
  	u_short    sa_family;
  	char       sa_data[14];
};  
struct sockaddr_in{
 	short sin_family;
	unsigned short sin_port;
 	IN_ADDR sin_addr;
 	char sin_zero[8];
};

另外,sockaddr_in结构中的sin_addr成员的类型是in_addr,其结构定义如下:

struct in_addr {
  union {
          struct { u_char s_b1,s_b2,s_b3,s_b4; }   S_un_b;
          struct { u_short s_w1,s_w2; }            S_un_w;
          u_long                                   S_addr;
  } S_un;
};

in_addr结构实际上是一个联合,通常利用这个结构将一个点分十进制格式的IP地址转换成u_long类型,并将结果赋给成员S_addr。

可以把IP地址指定为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或者接受数据。

b、inet_addr函数和inet_ntoa函数

多数情况下,每个机器只有一个IP地址,但是有的机器可能会有多个网卡,每个网卡都可以有自己的IP地址,用INADDR_ANY可以简化程序的编写,将地址指定为INADDR_ANY,将允许一个独立应用接受发自多个接口的回应。如果我们只想让套接字使用多个IP中的一个地址,就必须指定实际的地址,要做到这一点,可以用inet_addr函数来实现,该函数的原型声明如下:

unsigned long inet_addr (const char *cp ); 

inet_addr函数需要一个字符串作为其参数,该字符串指定了以点分十进制格式表示的IP地址。而且inet_addr函数会返回一个适合分配给S_addr的u_long类型的数值。

inet_ntoa函数会完成相反地转换,他接受一个in_addr结构体类型的参数并返回一个以点分十进制格式表示的IP地址字符串。该函数的原型声明如下:

char * inet_ntoa (struct in_addr in ); 

3、将套接字设为监听模式,准备接受客户请求(listen)

listen函数的作用是将指定的套接字设置为监听模式。其声明原型如下:

int listen (
SOCKET s,  //套接字描述符 
int backlog   等待连接队列的最大长度 
); 

对于第二个参数backlog,如果设置为SOMAXCONN,那么下层的服务提供者将负责将这个套接字设置为最大的合理值。要注意的是,设置这个值是为了设置等待连接队列的最大长度,而不是在一个端口上同时可以进行连接的数目。例如,如果将backlog参数设置为2,当有3个请求同时到来时,前两个连接请求就会被放到等待请求连接队列中,然后由应用程序依次为这些请求服务,而第3个连接请求就被拒绝了。

4、等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。

SOCKET accept(
SOCKET s, //套接字描述符,该套接字已经通过listen函数将其设置为监听状态
struct sockaddr *addr,  // 指向一个缓冲区的指针,该缓冲区用来接受连接实体的地址,也就是当客户端向服务器发起连接,服务器接受这个连接时,保存发起连接的这个客户端的IP地址信息和端口信息
int *addrlen   //也是一个返回值,指向一个整型的指针,返回包含地址信息的长度
); 

未完待续。。。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值