1.1 利用Socket实现双机通信

利用Socket实现双机通信

目的

  1. 利用WinSock来实现双机通信,理解TCP状态图
  2. 要求使用WinSock编程,采用其中的TCP面向连接方式,实现文本数据的交换。

环境

  1. Windows10操作系统、DevC++
  2. 对于使用MinGW的devc++,是没有ws2_32.lib这个库文件,它对应的库文件是libws2_32.a;可以在项目属性里的链接器添加这个库文件,或者在 工具->编译选项->在连接器命令行加入以下命令 中,删除原有命令,添加 -lws2_32 命令。

所需知识

  1. 计算机网络通讯
    (1)实质:进程之间的通讯
    (2)两台计算机之间通讯的基础:主机唯一标识符(IP)、进程唯一标识符(PORT)
  2. Socket简介
    (1)Socket是支持TCP/IP 协议的网络通信的基本单元
    (2)Socket包含5种信息:连接使用的协议,本机IP,本机PORT,远地主机IP,远地主机PORT。
    (3)Socket如何标识唯一进程的:通过IP地址标识网络中的唯一主机,通过传输层协议+PORT唯一标识主机中的进程。
    (4)Socket在网络结构中的位置:位于传输层与应用层之间。本质是一个编程接口,封装传输层为应用层提供服务。
    socket
    (5)Socket架构:C/S架构,典型的客户端、服务端架构。提供数据的传输服务。
  3. windows socket函数详解

(1)函数库头文件

#include <WinSock2.h> 
#pragma comment(lib,"Ws2_32.lib ")

(2)WSAStartup 初始化Ws2_32.dll的函数

int WSAStartup(__in WORD wVersionRequested,  __out LPWSADATA lpWSAData);
//WSAStartup 函数用于初始化供进程调用的Winsock相关的dll。
//wVersionRequested标识了用户调用的Winsock的版本号。通常使用MAKEWORD来生成一个版本号,现在一般为2。
//lpWSAData指向WSADATA结构体的指针,lpWSAData返回了系统对Windows Sockets 的描述。
//如果调用成功,WSAStartup 函数返回0。否则,将返回五种错误代码之一。但绝对不能使用WSAGetLastError获取错误代码。

(3)WSACleanup 释放Ws2_32.dll的函数

int WSACleanup(void);
//该函数释放对Winsock链接库的调用。

(4)socket 创建socket的函数

SOCKET WSAAPI socket( __in int af, __in int type,__in int protocol);
//socket函数将创建指定传输服务的socket。
//af:指明地址簇类型,常用的地址簇如下,其余地址簇在Winsock2.h中定义AF_INET(IPv4)、AF_INET6(IPv6)。
//type:指明socket的类型,常见类型:SOCK_STREAM(流套接字,使用TCP协议)、SOCK_DGRAM(数据报套接字,使用UDP协议)、SOCK_RAW(原始套接字)
//protocol:指明数据传输协议,该参数取决于af和type参数的类型。
//如果不出错,socket函数将返回socket的描述符(句柄),否则,将返回INVALID_SOCKET。

(5)bind 服务端将socket与地址关联

int bind( __in SOCKET s, __in const struct sockaddr* name, __in int namelen); 
//bind函数将socket关联一个本地地址。
//s:指定一个未绑定的socket。
//name:指向sockaddr地址的指针,该结构含有IP和PORT
//namelen:参数name的字节数。
//无错误返回0,有错误返回SOCKET_ERROR。

(6)listen 服务端网络监听

int listen( __in SOCKET s, __in int backlog );
//s:socket描述符,该socket是一个未连接状态的socket
//backlog:挂起连接的最大长度,如果该值设置为SOMAXCONN,负责socket的底部服务提供商将设置该值为最大合理值。并没有该值的明确规定。
//没有错误发生将返回0,否则返回SOCKET_ERROR 

(7) accept服务端connect接收

SOCKET accept(__in SOCKET s,__out struct sockaddr* addr, __in_out int* addrlen );
//accept函数将创建连接。
//s:listen函数用到的socket。
//addr:指向通信层连接实体地址的指针。addr 的格式取决于bind函数内地址簇的类型。
//addrlen:addr的长度
//如果不发生错误,accept将返回一个新的SOCKET描述符,即新建连接的socket句柄。否则,将返回INVALID_SOCKET。
//传进去的addrlen应该是参数addr的长度,返回的addrlen是实际长度。

(8)connect客户端请求服务端连接

int connect( __in SOCKET s,__in const struct sockaddr* name,__in int namelen );
//s:一个没有完成连接的socket;
//name:指向sockaddr地址的指针,该结构含有IP和PORT;
//namelen:参数name的字节数;
//返回0表示正确,否则,将返回SOCKET_ERROR。如果是阻塞式的socket连接,返回值代表了连接正常与失败。

(9)send、recv发送接收数据

int send(__in SOCKET s,__in const char* buf,__in int len,__in int flags );
int recv(__in SOCKET s,__out char* buf, __in int len, __in int flags );
//s:socket
//buf:数据buffer
//len:待发送/接收数据的长度
//flags:send(recv)函数的发送(接收)数据方式。
//send的返回值标识已发送数据的长度,这个值可能比参数len小,这也意味着数据缓冲区没有全部发出去,要进行后续处理。返回SOCKET_ERROR标识send出错。
//recv的返回值标识已接收数据的长度。如果连接已关闭,返回值将是0。返回SOCKET_ERROR标识recv出错。

(10)closesocket关闭socket

closesocket
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值