C/C++网络通讯编程(三)


一、Winsock

Winsock是一个基于Socket模型API,在Windows系统中广泛应用;它在Berkeley接口函数的基础上,还增加了基于消息驱动机制的Windows扩展函数;Winsocket1.1支持TCP/IP网络Winsock2.2增加了对更多协议的支持。

需要包含头文件Winsock2.h需要使用库2s2_32.lib包含办法可以用语句告诉编译时调用库:

#pragma comment(lib,”ws2_32.lib”);

二、Windows Socket的启动

使用函数WSAStartup()完成操作;

此函数的格式:int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);

 

三、创建套接口socket()

应用程序在使用套接口通信前,必须要拥有一个套接口,使用Socket()函数来给应用程序创建一个套接口。

SOCKET  socket(int af,  int type,  int protocol);    

协议

地址族

套接口类型

套接口类型使用的值

协议字段

互联网协议(IP)

AF_INET

TCP

SOCK_STREAM

IPPROTO_TCP

UDP

SOCK_DGRAM

IPPROTO_UDP

RAW

SOCK_RAW

IPPROTO_RAW ,  IPPROTO_ICMP

 

四、指定本地地址------bind()

socket()创建了一个套接口之后,需要将该套接口与该主机上提供服务的某端口联系在一起,bind()函数用于完成这样的绑定工作。

Int   bind(SOCKET  s,  const struct scokaddr FAR*name,   int namelen);  // 参数2 sockaddr_in结构指定IP地址和端口信息

 

五、服务器启动监听------listen()函数 

在一个服务器端用socket调用成功后一个套接口,并用bind函数和一个指定的地址关联后,就需要指示该套接口进入监听连接请求状态,这需要通过listen函数来实现。

Int  listen( SOCKET s,  int backlog);

 

六、客户端请求连接-----connect函数 

    Int  connect(SOCKET s, const struct sockaddr FAR*name, int namelen);

 

七、服务器端接受连接------accept()函数

SOCKET accept(SOCKET s,  struct scokaddr FAR* addr, int FAR*addrlen);

 

八、发送数据------send()函数 

Int send(socket s,  const char FAR* buf,  int len,  int flags);

 

九、接受数据------recv()函数

    Int  recv(SOCKET S,  char FAR*buf,  int len,  int flags);

 

十、无连接的套接口上接收数据------recvfrom()

    Int  recvfrom(SOCKET s,  char FAR*buf,  int len,  int flags,  struct sockaddr FAR*from,  int FAR* fromlen);

 

十一、在无连接套接口上发送数据-sendto()

    Int  sendto(SOCKET s,  const char FAR* buf,  int len,  int flags,  const struct sockaddr FAR* to,int tolen);

    

十二、关闭读写通道------shutdown()函数

    Int  shutdown(SOCKET s,  int how);  // how: 0 1 2

 

十三、关闭套接口------closesocket()函数

    Shutdown函数只关闭读写通道,并不关闭套接口,且套接口所占有资源将被一直保留到closesokcet调用之前。

    Int  closesocket( SOCKET s);

 

十四、IP地址转换函数

1. Char *inet_ntoa(struct in_addr in);            // 把32数字表示为IP地址

2. Unsigned long inet_addr(const char FAR * cp);   // 把IP地址转换为32数字

3.u_long htonl(u_long hostlong);      // 4 bytes

4.u_short htons(u_short hostshort);   // 2bytes

5.u_long ntohl(u_long netlong);       // 4bytes

6.u_short ntohs(u_short netshort);    // 2bytes

 

十五、终止使用Winsock—WSACLeanup()函数

   当应用程序不再使用Winsock API的任何函数时,必须调用WASCeanup()将其从Windows Socket实现中注销,以释放为此应用程序或DLL分配的任何资源。

 

第二节

一、 面向连接的C/S程序工作流程(TCP

1. 服务器端工作流程

l 使用WSAStartup()函数检查系统协议栈安装情况

l 使用socket()函数创建服务器通信套接口

l 使用bind()函数将创建的套接器与服务器地址绑定

l 使用listen()函数使用服务器接口做那接收连接请求的准备

l 使用accept()接收来自客户端由connect()函数发出的连接请求

l 根据连接请求建立连接后,使用send()函数发送数据,或者使用recv()函数接收数据

l 使用closesocket()函数关闭套接口中,也可以先使用shutdown()函数先关闭读写通道

l 最后调用WSACeanup()函数结束Winsock Sockets API

 

2. 客户端程序工作流程

l 使用WSAStartup()函数检查系统协议栈安装情况

l 使用socket()函数创建客户端套接口

l 使用connect()函数发出也服务器建立连接请求(调用前可以不用bind()端口号,由系统自动生成完成)

l 连接建立后使用send()函数发送数据,或使用recv()函数接收数据

l 使用closesocket()函数关闭套接口

l 最后调用WSACleanup()函数,结束Winsock Sockets API

 

3. 服务器与客户端五元组的建立

五元组

《协议》

《本地IP地址,本地端口号》

《远程IP地址,远程端口号》

服务器五元组

socket()确定

由服务器端调用bind()确定

accept()确定

客户端五元组

socket()确定

由客户端的bind()调用确定。如果客户端没有进行bind()调用,或调用了bind()没有指定具体的地址或端口,则由系统内核自动确定地址和端口

 

 

4.面向连接的C/S程序工作流程图(TCP)

 

 

 

二、 无连接的C/S程序工作流程(UDP

1、 无连接的数据报传输服务通信时,客户端与服务器端所使用的函数是类似的,其工作流程如下:

l 使用WSAStartup()函数检查系统协议栈的安装情况

l 使用socket()函数创建套接口,以确定协议类型

l 调用bind()函数将创建的套接口与本地地址绑定,确定本地地址和本地端口

l 使用sendto()函数发送数据,或者使用recvfrom()函数接收数据

l 使用closesocket()函数关闭套接口

l 调用WSACleanup()函数,结束Windows Sockets API

 

2.注意事项:

l 通信一方可以不用bind()绑定地址和端口,由系统分配

l 不绑定IP地址和端口号的一方必须首先向绑定地址的一方发送数据

l 无连接的应用程序也可以调用connect()函数,但是它并不向对方发出建立连接的请求,而是在本地返回,由内核将connect()中指定的目标IP地址和端口号记录下来,在以后的通信中就可以使用面向连接的数据发送函数send()数据接收函数recv().

l 无连接的数据报传输过程中,作为服务器一方必须先启动

l 无连接客户端一般不调用connect(),在数据发送前客户与服务器各自通过socket()bind()建立了半相关,发送数据时除指定本地套接口的地址外,还需要指定收方套接口地址,从而在数据收发过程中动态建立全连接。

 

 

三、阻塞通信与非阻塞通信

阻塞方式:套接字进行I/O操作时,函数要等待到相关的操作完成以后才能返回,对提高处理机的利用率不利,但编程简单。

非阻塞方式:套接字进行I/O操作时,无论操作成功与否,调用都会立即返回。

阻塞方式编程简单,一个套接口的默认操作模式为阻塞,可以调用函数ioctlsocket()进行设置。

 

三、并发服务器

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值