本节关于socket部分函数库列表,具体基于socket的实例实现代码见下节。给出基于winSocket的简单websever实例。


2.1 WSAStartup()

【函数原型】

int WSAStartup (WORD wVersionRequested,  LPWSADATA  lpWSAData  );

【参数】

wVersionRequested
[in] 表示欲使用的Windows Sockets API版本;这是个WORD类型的整数,高字节定义的是次版本号,低字节定义的是主版本号。lpWSAData
[in] 指向WSAData资料的指针。WSAData是结构数据类型,描述了关于Windows Sockecs底层实现的相关信息。

【返回值】

函数执行成功返回0,失败则返回如下错误代码:WSASYSNOTREADY: 底层网络子系统没有准备好。WSAVERNOTSUPPORTED:Winsock版本信息号不支持。WSAEINPROGRESS: 阻塞式Winsock1.1存在于进程中。WSAEPROCLIM: 已经达到Winsock使用量的上限。WSAEFAULT: lpWSAData不是一个有效的指针。

【函数功能】

这个函数是应用程序应该第一个调用的Winsock API函数,以完成一系列初始化的工作。

【相关数据结构】

WSADATA的定义如下:
typedef struct WSAData {WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, FAR * LPWSADATA;

其中,各结构成员的含义为:

wVersion
应用程序应该使用的Winsock版本号。wHighVersion
DLL所支持的最高版本号。通常应该等于wVersion。szDescription
以0结尾的ASCII字符串,关于Winsock底层实现的描述信息。szSystemStatus
以0结尾的ASCII字符串,关于Winsock底层状态或者配置信息。iMaxSockets
一个进程最多可使用的套接字数,仅用于Winsock1.1,Winsock 2.0应该忽略该成员。iMaxUdpDg
最大的UDP报文大小,仅用于Winsock1.1,Winsock 2.0应该忽略该成员。对于Winsock 2.0,应该使用getsockopt函数取得SO_MAX_MSG_SIZE。lpVendorInfo
Winsock开发厂商信息,,仅用于Winsock1.1,Winsock 2.0应该忽略该成员。对于Winsock 2.0,应该使用getsockopt函数取得PVD_CONFIG。

【示例代码】

#include <winsock.h>
//对于Winsock 2, include <winsock2.h>WSADATA  wsaData;
int nRc = WSAStartup(0x0101, & wsaData);
if(nRc)
{//Winsock初始化错误
return;
}
if(wsaData.wVersion != 0x0101)
{//版本支持不够
//报告错误给用户,清除Winsock,返回
WSACleanup();
return;
}

2.2 socket()

【函数原型】

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

【参数】

af
[in] 指定地址族(address family),一般填AF_INET(使用Internet地址)。type
[in] 指定SOCKET的类型:SOCK_STREAM(流类型),SOCK_DGRAM(数据报类型)。protocol
[in] 指定af参数指定的地址族所使用的具体一个协议。建议设为0,那么它就会根据地址格式和SOCKET类型,自动为你选择一个合适的协议。另外2个常用的值为:IPPROTO_UDP和IPPROTO_TCP。

【返回值】

函数执行成功返回一个新的SOCKET,失败则返回INVALID_SOCKET。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

所有的通信在建立之前都要创建一个SOCKET。

【示例代码】

//创建数据报socket
SCOKET udpSock = socket(AF_INET,
SOCK_DGRAM, IPPROTO_UDP);
//创建流socket
SCOKET tcpSock = socket(AF_INET,
SOCK_STREAM, IPPROTO_TCP);

2.3 bind()

【函数原型】

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

【参数】

s
[in] 一个需要绑定的SOCKET,例如用socket函数创建的SOCKET。name
[in] 指向描述通信对象地址信息的结构体sockaddr的指针。在该结构体中可以指定地址族(一般为 AF_INET)、主机的地址和端口。通常把主机地址指定为INADDR_ANY(一个主机可能有多个网卡)。namelen
[in] name指针指向的结构体的长度。

【返回值】

函数执行成功返回0,失败则返回SOCKET_ERROR。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

成功地创建了一个SOCKET后,用bind函数将SOCKET和主机地址绑定。

【相关数据结构】

struct sockaddr {u_short sa_family;
char sa_data[14];
};

sa_family
地址族,比如AF_INET,2个字节大小。sa_data
用来存放地址和端口,14个字节大小。
sockaddr结构是一个通用的结构(因为Winsock支持的协议族不只是TCP/IP)。对TCP/IP协议,用如下结构来定义地址和端口。

struct sockaddr_in {short sin_family;
u_short sin_port;
struct  in_addr sin_addr;
char sin_zero[8];
};

sin_family
地址族,设为AF_INET。sin_port
端口号。如果端口号为0,Winsock会自动为应用程序分配一个值在1024-5000间的一个端口号,所以客户端一般把sin_port设为0。sin_addr
为in_addr结构类型,用来指定IP地址。通常把主机地址指定为INADDR_ANY(一个主机可能有多个网卡)。结构in_addr下面介绍。sin_zero
8字节的数组,值全为0。这个8个字节用来填充结构sockaddr_in使其大小等于结构sockaddr(16字节)。

结构in_addr用来指定IP地址,其定义为:

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;
};

对于IP地址10.14.25.90,sockaddr_in结构中的sin_addr可以这样赋值:

sin_addr. S_un .S_un_b. s_b1 = 10;
sin_addr. S_un .S_un_b. s_b2 = 14;
sin_addr. S_un .S_un_b. s_b3 = 25;
sin_addr. S_un .S_un_b. s_b4 = 90;

或者

sin_addr. S_un . S_un_w. s_w1 = (14<<8)|10;
sin_addr. S_un . S_un_w. s_w2 = (90<<8)|25;

或者

sin_addr. S_un . S_addr = (90<<24)|(25<<16)|(14<<8)|10;

或者

sin_addr. S_un . S_addr = inet_addr(“10.14.25.90”);

这里的inet_addr函数可以将字符串形式的IP地址转换为unsigned long形式的值。

【示例代码】

SOCKET sServSock;
sockaddr_in addr;//创建socket
sServSock = socket(AF_INET, SOCK_STREAM, 0);addr.sin_family = AF_INET;//htons和htonl函数把主机字节顺序转换为网络字节顺序,分别用于//短整型和长整型数据
addr.sin_port = htons(5050);
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); // LPSOCKADDR类型转换是必须的
int nRc = bind(sServSock, (LPSOCKADDR)&addr, sizeof(addr) );

2.4 listen()

【函数原型】

int listen (SOCKET s,  int backlog);

【参数】

s
[in] 一个已经绑定但未连接的SOCKET。backlog
[in] 等待连接的队列的长度,可取SOMAXCONN。如果某个客户程序要求连接的时候,服务器已经与其他客户程序连接,则后来的连接请求会放在等待队列中,等待服务器空闲时再与之连接。当等待队列达到最大长度(backlog指定的值)时,再来的连接请求都将被拒绝。

【返回值】

函数执行成功返回0,失败则返回SOCKET_ERROR。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

对于服务器的程序,当申请到SOCKET,并将通信对象指定为INADDR_ANY之后,就应该等待一个客户机的程序来要求连接,listen函数就是把一个SOCKET设置为这个状态。

2.5 accept()

【函数原型】

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

【参数】

s
[in] 一个已经处于listen状态的SOCKET。addr
[out] 指向sockaddr结构体的指针,里面包含了客户端的地址和端口。addrlen
[out] int型指针,指向的内容为addr指针指向的结构体的长度。

【返回值】

如果函数执行成功,会建立并返回一个新的SOCKET来与对方通信,新建的SOCKET与原来的SOCKET(函数的第一个参数s)有相同的特性,包括端口号。原来的SOCKET继续等待其他的连接请求。而新生成的SOCKET才是与客户端通信的实际SOCKET。所以一般将参数中的SOCKET称作“监听”SOCKET,它只负责接受连接,不负责通话;而对于函数返回的SOCKET,把它称作“会话”SOCKET,它负责与客户端通话。
如果失败则返回INVALID_SOCKET。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

accept函数从等待连接的队列中取第一个连接请求,并且创建一个新的SOCKET来负责与客户端会话。

【示例代码】

SOCKET sServSock; //服务器监听socket
sockaddr_in addr;
int nSockErr;
int nNumConns = 0; //当前请求连接数
SOCKET sConns[5]; //会话SOCKET数组
sockaddr ConnAddrs[5];//请求连接的客户端地址
int nAddrLen;//创建服务器监听socket
sServSock = socket(AF_INET, SOCK_STREAM, 0);addr.sin_family = AF_INET;
addr.sin_port = htons(5050);
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);if( bind(sServSock,(LPSOCKADDR)&addr,sizeof(addr)) ==
SOCKET_ERROR )
{nSockErr = WSAGetLastError();
//绑定出错处理
}
//监听客户端请求连接
if( listen(sServSock, 2)  ==  SOCKET_ERROR)
{nSockErr = WSAGetLastError();
//出错处理
}while( nNumConns < 5){//每当收到客户端连接请求,创建新的会话SOCKET,保存在/ //sConns数组中
//客户端地址保存在ConnAddrs数组中
sConns[nNumConns] = accept(sServSock,
ConnAddrs[nNumConns], &nAddrLen);
if(sConns[nNumConns] == INVALID_SOCKET)
{nSockErr = WSAGetLastError();
//创建会话SOCKET出错处理
}
else
{//创建会话SOCKET成功,启动新的线程与客户端会话
StartNewHandlerThread(sConns[nNumConns]);
//当前请求连接数+1
nNumConns ++;
}
}

2.6 connect()

【函数原型】

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

【参数】

s
[in] 一个未连接SOCKET,一般是由socket函数建立的。name
[in] 同bind函数。namelen
[in] 同bind函数。

【返回值】

函数执行成功返回0,失败则返回SOCKET_ERROR。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

向对方主动提出连接请求。

2.7 send()

【函数原型】

int send (SOCKET s, char * buf, int len ,int flags);

【参数】

s
[in] 一个已经连接的SOCKET。buf
[in] 指向要传输的数据的缓冲区的指针。len
[in] buf的长度。flags
[in]指定函数调用的方式。一般取0。

【返回值】

函数执行成功返回发送的字节数(可能小于len),失败则返回SOCKET_ERROR。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

通过已经连接的SOCKET发送数据。

2.8 recv()

【函数原型】

int recv (SOCKET s, char * buf, int len ,int flags);

【参数】

s
[in] 一个已经连接的SOCKET。buf
[out] 指向接收数据的缓冲区的指针。len
[in] buf的长度。flags
[in]指定函数调用的方式。一般取0。

【返回值】

函数执行成功返回接收到数据的字节数。如果失败则返回SOCKET_ERROR。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

通过已经连接的SOCKET接收数据。当读到的数据字节少于规定接受的数目(len)时,就把数据全部接收,并返回实际接收到的字节数;当读到的数据多于规定的值时,在流方式下剩余的数据由下个recv读出,在数据报方式下多余的数据被丢弃。

2.9 sendto()

【函数原型】

int sendto (SOCKET s, char * buf, int len ,int flags, struct sockaddr_in * to, int tolen);

【参数】

s
[in] 一个SOCKET(可能已连接)。buf
[in] 指向要传输的数据的缓冲区的指针。len
[in] buf的长度。flags
[in] 指定函数调用的方式。一般取0。to
[in] 指向目标地址结构体的指针。tolen
[in] 目标地址结构体的长度。

【返回值】

函数执行成功返回发送的字节数(可能小于len),失败则返回SOCKET_ERROR。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

该函数一般用于通过无连接的SOCKET发送数据报文,报文的接受者由to参数指定。

2.10 recvfrom()

【函数原型】

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

【参数】

s
[in] 一个已经绑定的SOCKET。buf
[out] 指向接收数据的缓冲区的指针。len
[in] buf的长度。flags
[in] 指定函数调用的方式。一般取0。from
[out] 指向源地址结构体的指针。fromlen
[in/out] 源地址结构体的长度。

【返回值】

函数执行成功返回发送的字节数(可能小于len),失败则返回SOCKET_ERROR。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

该函数一般用于通过无连接的SOCKET接收数据报文,报文的发送者由from参数指定。

2.11 closesocket()

【函数原型】

int closesocket (SOCKET s,);

【参数】

s
[in] 要关闭的SOCKET。

【返回值】

函数执行成功返回0,失败则返回SOCKET_ERROR。这时可以调用WSAGetLastError函数取得具体的错误代码。

【函数功能】

关闭指定的SOCKET。

qt socket 传递结构体 结构体中有list_计算机网络应用--Socket编程实验(二)相关推荐

  1. 三、初识Socket套接字结构体

    一.初识Socket套接字结构体 1.通用套接字结构体类型 struct sockaddr{sa_family_t sa_family; //协议簇char sa_data[14]; //协议簇数据} ...

  2. python中的记录指针_使用Python向C语言的链接库传递数组、结构体、指针类型的数据...

    使用python向C语言的链接库传递数组.结构体.指针类型的数据 由于最近的项目频繁使用python调用同事的C语言代码,在调用过程中踩了很多坑,一点一点写出来供大家参考,我们仍然是使用ctypes来 ...

  3. python结构体数组传出接收c动态库_使用Python向C语言的链接库传递数组、结构体、指针类型的数据...

    使用python向C语言的链接库传递数组.结构体.指针类型的数据 由于最近的项目频繁使用python调用同事的C语言代码,在调用过程中踩了很多坑,一点一点写出来供大家参考,我们仍然是使用ctypes来 ...

  4. 如何通过结构化智能体完成物理构造任务?| 技术头条

    作者 | Victor Bapst, Alvaro Sanchez-Gonzalez,Carl Doersch, Kimberly L. Stachenfel 译者 | Linstancy 编辑 | ...

  5. c语言结构体共用体枚举实例程序,10-C语言结构体-共用体-枚举

    结构体是什么? 结构体和数组一样属于构造类型 数组是用于保存一组相同类型数据的,而结构体是用于保存一组不同类型的数组 定义结构体 在使用结构体之前必须先定义结构体类型,因为C语言不知道你的结构体中需要 ...

  6. C++ 基础入门 之 结构体/结构体定义和使用/结构体数组/结构体指针/ 结构体嵌套结构体/结构体做函数参数/结构体中 const 使用场景/结构体案例

    C++ 基础入门 之 结构体/结构体定义和使用/结构体数组/结构体指针/ 结构体嵌套结构体/结构体做函数参数/结构体中 const 使用场景/结构体案例 目录 一.简单介绍 二.结构体定义和使用 三. ...

  7. 【结构体】 结构体引用、结构体数组指针、包含结构的结构体

    目录 一.概念.变量的定义 初识结构体 结构体变量的定义.引用结构体类型的初始化 二.结构体的数组 认识结构体数组 初始化结构体数组 三.结构体指针 初识结构体指针 指向结构体数组的指针 结构体作为函 ...

  8. 2020.1.13 C语言学习 结构体+结构体数组+结构体指针

    结构体 结构体的形式 struct 结构体名称 { 结构体成员1; 结构体成员2; - }; 例如: 图书的结构体 struct Book {char title[128];char author[4 ...

  9. C++结构体 结构体定义和使用、结构体数组、结构体指针、结构体嵌套结构体、结构体做函数参数

    C++结构体 第二章 C++结构体 1.结构体定义和使用 语法:struct 结构体名 { 结构体成员列表 }: 通过结构体创建变量的方式有三种: struct 结构体名 变量名 struct 结构体 ...

最新文章

  1. python内置库之学习ctypes库(三)--调用Win32API
  2. 如何修改可运行Jar包,如何反编译Jar包
  3. Spring JDBC-事务方法嵌套调用解读
  4. BlockingQueue常用方法add、off、put、take、poll使用说明
  5. 如何在pycharm添加扩张工具
  6. 敏捷冲刺每日报告——Day5
  7. 前端:常用的meta标签总结
  8. ASP.NET Core on K8S学习初探(3)部署API到K8S
  9. mysql占用内存吗_mysql占多少内存
  10. Gartner:阿里云蝉联全球第三、亚太第一
  11. jquery validate 联动验证
  12. 分享Silverlight/WPF/Windows Phone/HTML5一周学习导读(2月13日-2月19日)
  13. ps软件打不开计算机受限制,win10系统打不开ps软件的处理技巧
  14. vue @cliick.stop @click.prevent @click.self
  15. if语句与switch语句
  16. 联想服务器怎么做系统备份,联想笔记本怎么做系统备份
  17. 【调剂】211北京科技大学钢铁共性技术协同创新中心2020年硕士研究生招生拟接收调剂公告...
  18. Linux命令:Nginx的启动、停止与重启
  19. JS设置select标签选中的值
  20. Mongodb 3.6安装过程(centos7.9)

热门文章

  1. 使用C语言将一个数组首尾互换后输出,函数实现体会地址传递
  2. 测验8.2 指针与字符串 6-1 函数实现字符串逆序
  3. sys接口linux编程,网络编程常用接口的内核实现----sys_listen()
  4. c语言中switch语句流程图_C语言:C语言保留字(关键字)
  5. 小程序如何选择云服务器,小程序怎么选择云服务器配置
  6. java 重复提交_java解决重复提交表单
  7. Java黑皮书课后题第2章:2.18(打印表格)编写程序,显示下面的表格,将浮点数值类型转化为整数
  8. android动态获取输入值,Android实现动态自动匹配输入内容
  9. 2006---2009年杭电计算机历年研究生复试---笔试编程
  10. 【easy】206. Reverse Linked List 链表反转