- 浏览: 278943 次
- 性别:
文章分类
最新评论
源自:http://blog.sina.com.cn/s/blog_a459dcf5010155nf.html
本文针对SOCKET编程中要用到的函数进行一个比较系统的介绍。
说明:在使用Socket时,需要在lib库中使用ws2_32.lib;
1、WSAStartup:初始化套接字环境,本函数必须是应用程序或DLL调用的第一个Windows Sockets函数.它允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节.应用程序或DLL只能在一次成功的WSAStartup()调用之后才能调用进一步的Windows Sockets API函数.
int WSAStartup(
WORD wVersionRequested,
LPWSADATA lpWSAData
);
下面给出WSAStartup函数在实际开发过程中的用法:
//begin 初始化网络环境
int err = WSAStartup(MAKEWORD(2, 2), &wsaData);
if ( err != 0)
{
printf("WSAStartup failed with error: %d\n", err);
return -1;
}//end
2、WSACleanup:清理套接字环境,和上面的WSAStartup相反,该函数是在程序不在对任何Windows Sockets函数调用后,用其来清理套接字环境的
int WSACleanup (void);
3、SOCKET socket(int af, int type, int protocol);
建立套接字
参数af用于指定网络地址类型,一般取AF_INET,表示该套接字在Internet域中,进行通信。
参数type用于知道套接字的类型,若取SOCK_STREAM表示创建的套接字是流套接字,而取SOCK_DGRAM创建数字报套接字。
参数protocol用于指定网络协议,一般取0,表示默认为TCP/IP协议。
若套接字创建成功则该函数返回创建的套接字句柄SOCKET,否则产生INVALID_SOCKET错误。
下面给出WSACleanup、socket函数在实际开发过程中的用法:
//begin socket 一个套接字
hTcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == hTcpSocket)
{
MJS_LOG_ERROR("socket failed with error: \n");
WSACleanup();
return -1 ;
}//end
4、int listen(SOCKET s, int backlog);
将套接字置入监听模式并准备接受连接请求。其中,参数s是服务器端套接字,于指定正在等待连接的最大队列长度。如无错误发生,listen函数返回0,失败则返回SOCKET_ERROR错误。
5、SOCKET accept( SOCKET s, struct sockaddr* addr, int* addrlen );
参数s同上,addr是一个有效的SOCKADDR_IN结构的地址,而addrlen是sockaddr_in结果的长度。accept函数返回后,addr参数变量中会包含发出连接请求的那个客户机的IP地址信息,而addrlen参数则指出该结构的长度,并返回一个新的套接字描述符,它对应于已经接受的那个客户机连接。
6、 int bind( SOCKET s, const struct sockaddr* name, int namlen );绑定到本地,name中指定的IP应该是当前运行该程序机器的IP。
7、int connect( SOCKET s, const struct sockaddr FAR* name, int namelen );连接到服务器
下面给出connect函数在实际开发过程中的用法:
int ServePort=20000;
char ServeIP[32]="192.168.1.200";
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(ServePort);
addr.sin_addr.S_un.S_addr = inet_addr(ServeIP);
//连接服务器
if (connect(hTcpSocket, (sockaddr*)&addr, sizeof(sockaddr)) == -1)
{
closesocket(hTcpSocket);
printf("connect Tradesys failed with error%d,%s,%d: \n",ServePort,ServeIP,GetLastError());
WSACleanup();
return -1;
}
else
{
printf("connect Tradesys sucessed,%d,%s: \n",ServePort,ServeIP);
}
8、 int send( SOCKET s, const char* buf, int len, int flags );
s是已建立连接的套接字描述字,参数buf是字符缓冲区,包含即将发送的数据,参数len用于指定即将发送的缓冲区内的字符数。flags可取的值有:0、MSG_DONTROUTE或MSG_OOB或这些标志的按位或运算。
9、int recv( SOCKET s, char* buf, int len, int flags );
s是准备接收数据的套接字,buf是即将收到数据的字符缓冲区,而len则是准备接受的字节数或buf缓冲的长度。flags参数可以是0、MSG_PEEK或MSG_OOB或这些标志的按位“或”运算。
10、int shutdown( SOCKET s, int how );
其中,how参数用于描述禁止哪些操作,它可取的值有:SD_RECEIVE、SD_SEND或SD_BOTH。
如果是SD_RECEIVE,就表示不允许再调用接收函数,
如果选择SD_SEND,表示不允许再调用发送函数,
如果是SD_BOTH, 则表示取消连接两端的收发操作。
如果没有错误发生,shutdown()返回0,否则返回SOCKET_ERROR错误。
11、 int closesocket(SOCKET s );s是要关闭的套接字描述字,再利用套接字执行调用就会失败。
12 int gethostname(char *name, size_t len):这个函数,调用后,会将主机名保存在name里面。而len是name的大小。该函数返回0表示成功,否则失败。
13、struct hostent *gethostbyname(const char *name);
hostent结构:
struct hostent {
char *h_name;//*h_name 表示的是主机的规范名
char **h_aliases;//h_aliases 表示的是主机的别名
int h_addrtype;//地址类型AF_INET,还是AF_INET6
int h_length;//IP地址占字节数
char **h_addr_list;//IP地址列表
};
char *h_name 表示的是主机的规范名。
char **h_aliases 表示的是主机的别名。
int h_addrtype 表示的是主机ip地址的类型,到底是ipv4(AF_INET),还是ipv6(AF_INET6)
int h_length 表示的是主机ip地址的长度
int **h_addr_lisst 表示的是主机的ip地址,注意,这个是以网络字节序存储的。
14、const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) ;
这个函数,是将类型为af的网络地址结构src,转换成主机序的字符串形式,存放在长度为cnt的字符串中。这个函数,其实就是返回指向dst的一个指针。如果函数调用错误,返回值是NULL。
15、struct hostent FAR *PASCAL FAR gethostbyaddr(const char FAR * addr, int len, int type);
参数addr:指向网络字节顺序地址的指针。
参数len: 地址的长度,在PF_INET类型地址中为4。
参数type:指地址类型AF_INET、IF_INET6
16、inet_ntoa( char FAR* PASCAL FAR inet_ntoa( struct in_addr in);
将网络地址转换成“.”点隔的字符串格式。本函数将一个用in参数所表示的Internet地址结构转换成以“.” 间隔的诸如“a.b.c.d”的字符串形式。请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。应用程序不应假设该内存是如何分配的。在同一个线程的下一个WINDOWS套接口调用前,数据将保证是有效。
参数in:一个表示Internet主机地址的结构。
返回值:若无错误发生,inet_ntoa()返回一个字符指针。否则的话,返回NVLL。其中的数据应在下一个WINDOWS套接口调用前复制出来。
上面这几个函数对于完成简单的连接操作是可以胜任的,但是在真正的使用过程中,将会用到更多的函数。
17、unsigned long inet_addr( const char FAR *cp); 将点格式的IP地址转换为无符号类型存储。
18、u_short PASCAL FAR htons( u_short hostshort); 作用是将主机的无符号短整形数转换成网络字节顺序。
19、 u_short PASCAL FAR ntohs( u_short netshort);
20、u_long PASCAL FAR htonl( u_long hostlong);
本函数将一个32位数从主机字节顺序转换成网络字节顺序。
//将主机的unsigned long值转化为网络字节顺序(32位),使用函数htonl()
//参数hostlong标识主机字节顺序的数字,函数返回一个网络字节顺序的数字
#include <winsock.h>
#include <stdio.h>
#pragma comment (lib,"ws2_32.lib")
void main()
{
u_long a = 0x12345678;
u_long b = htonl(a);
printf("%u/n",a);
printf("%x/n",a);
printf("%u/n",b);
printf("%x/n",b);
}
21、u_long PASCAL FAR ntohl( u_long netlong);
将一个无符号长整形数从网络字节顺序转换为主机字节顺序。
参数netlong:一个以网络字节顺序表达的32位数。
返回值:ntohl()返回一个以主机字节顺序表达的数。
//将32位网络字节转换为主机字节,使用函数ntohl()
//定义如下 u_long ntohl(u_long netlong);
#include <WINSOCK2.H>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
void main()
{
u_long a = 0x12345678;
u_long b = ntohl(a);
printf("%u/n",a);
printf("%x/n",a);
printf("%u/n",b);
printf("%x/n",b);
}
22、int PASCAL FAR getpeername( SOCKET s, struct sockaddr FAR* name, int FAR* namelen);
参数s:标识一已连接套接口的描述字。
参数name:接收端地址的名字结构。
参数namelen:一个指向名字结构的指针。
getpeername()函数用于从端口s中获取与它捆绑的端口名,并把它存放在sockaddr类型的name结构中。 它适用于数据报或流类套接口。 返回值: 若无错误发生,getpeername()返回非零。否则的话,返回0,应用程序可通过WSAGetLastError()来获取相应的错误代码。
23、int PASCAL FAR getsockname( SOCKET s, struct sockaddr FAR* name, int FAR* namelen); 获取一个套接口的本地名字。
s:标识一个已捆绑套接口的描述字。
name:接收套接口的地址(名字)。
namelen:名字缓冲区长度。
getsockname()函数用于获取一个套接口的名字。 它用于一个已捆绑或已连接套接口s,本地地址将被返回。
本调用特别适用于如下情况:未调用bind()就调用了connect(),这时唯有getsockname()调用可以获知系统内定的本地地址。 在返回时,namelen参数包含了名字的实际字节数。 若一个套接口与INADDR_ANY捆绑,也就是说该套接口可以用任意主机的地址, 此时除非调用connect()或accept()来连接,否则getsockname()将不会返回主机IP地址的任何信息。 除非套接口被连接,WINDOWS套接口应用程序不应假设IP地址会从INADDR_ANY变成其他地址。 这是因为对于多个主机环境下,除非套接口被连接,否则该套接口所用的IP地址是不可知的。 返回值: 若无错误发生,getsockname()返回0。 否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。
附:22、23函数中错误代码:
WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()。
WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。
WSAEFAULT:namelen参数不够大。
WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。
WSAENOTCONN 套接口未连接。
WSAENOTSOCK:描述字不是一个套接口。
WSAEINVAL:套接口未用bind()捆绑。
24、int PASCAL FAR setsockopt( SOCKET s, int level, int optname, const char FAR* optval, int optlen);
关于该函数的介绍请参考下面连接:http://blog.sina.com.cn/s/blog_a459dcf5010155nb.html
25、int PASCAL FAR getsockopt( SOCKET s, int level, int optname, char FAR* optval, int FAR* optlen);
关于该函数的介绍请参考下面连接:http://blog.sina.com.cn/s/blog_a459dcf5010155nb.html
发表评论
-
C中结构体
2013-01-09 15:47 588把结构体保存到文件中,用fwrite()函数: fwrite ... -
C中需要注意的小问题
2012-09-27 08:59 7801.在用scanf()函数读入double型数值时要用%lf的 ... -
指针和多维数组
2011-12-26 10:03 782摘自:《C primer plus》 指针和多位数组 ... -
C中<ctype.h>库
2011-12-19 20:21 692标准库<ctype.h> 1 ... -
C中double类型数据的输入和输出
2011-12-19 10:04 12345double a; scanf(" ... -
C中printf()和scanf()函数说明
2011-12-16 19:58 1553下面是对printf()和scanf()函数的说明: ... -
C中转义序列及其含义
2011-12-15 20:27 939转义序列: 序列 ... -
C中各数据类型取值范围
2011-12-15 19:31 13621.标准头文件<limits.h>中包含了 ... -
C中常用的类型转换函数
2011-12-14 17:34 781源自:http://hi.baidu.com/hao_%BF% ... -
C语言格式化输出系统时间
2011-12-14 17:04 5897源自:http://blog.csdn.net/jiadeli ... -
C中目标代码文件,可执行文件和库
2011-12-14 10:19 1930C编程的基本策略是使用程序将源代码文件转换为可执行 ... -
vs2008下vc的库函数及头文件存放位置
2011-12-13 22:14 4504在写C/C++程序时总会在开头包含一些头文件,如:#inclu ... -
malloc()函数
2011-12-12 17:35 0待写 -
用C写的模拟掷骰子程序
2011-12-12 16:47 2317整理自:《C Primer Plus》第五版 此程序包 ... -
C中字符串的输入输出及相关函数
2011-12-27 21:59 3818//本节内容摘自对Stephen Prata的《C Prime ... -
指针的基本操作以及关于指针的注意事项
2011-12-11 17:42 893一. 指针的基本操作有:赋值(assignment),求值(v ... -
关于*与++的优先级
2011-12-11 16:53 1657C中一元运算符*和++具有相等的优先级,但它们在结合时是从右向 ... -
C中关于数组参数的传递
2011-12-09 11:43 891编写一个对数组进行操作的函数,目的是返回数组内所用元素的和。 ... -
C中有关数组的说明
2011-12-09 11:10 745下面介绍一下关于数组的一些说明: 在数组声明时必须 ... -
C语言中对sizeof()和strlen()的说明
2011-12-09 10:01 10911.sizeof函数 sizeof函数返回表达式所占的内存空 ...
相关推荐
该文档较为详细的解说了Socket编程基本的函数
socket编程中的常用函数,详细的函数说明
这是的在学习中对socket编程中一些函数的理解,和大家分享一下。
Socket编程所有函数说明[详细],文档排版整齐。
关于SOCKET中的accept函数的解释,可以让你更清楚的了解SOCKET编程
本资料提供的是用Socket编程实现聊天程序。 有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,...
详细讲述了网络编程socket bind函数的使用说明
C++ SOCKET编程介绍
Socket编程 IP地址 端口号 Socket Socket SOCKET连接过程 Socket常用函数介绍 服务端监听Socket创建步骤 客户端连接Socket创建步骤 IP地址是Internet中主机的标识 Internet中的主机要与别的机器通信必须具有一个IP...
socket编程接口调用函数以及示例[总结].pdf
第六章 Socket编程 1、什么是套接字 套接字是一组用于编写网络程序的API 常见的套接字有: --Windows平台 WinSock --Unix/Linux socket 套接字类型: --stream socket 面向流的一种套接字。 --datagram socket...
socket编程头文件和常用函数.doc
介绍 UNIX Socket编程的基本概念及函数说明
C++网络编程socket编程
有关socket编程的函数详解 给出这些函数的参数以及相关的作用是什么~
使用msdn虽然比较精确,但是对于英文不是很好,又想准确理解socket各类函数的使用,该资源里面的word文档记录了使用socket编程的各种函数中文说明,对于编写各种socket程序很有帮助。
Socket 编程让你沮丧吗?从man pages中很难得到有用的信息吗?你想跟上时代去编Internet相关的程序,但是为你在调用 connect() 前的bind() 的结构而不知所措?等等… 好在我已经将这些事完成了,我将和所有人共享...
基于TCP的协议的Socket编程,介绍UDP编程的基本函数用法,word文档
socket编程中select的使用Select在Socket编程中还是比较重要的,可是对于初学Socket的人来 说都不太爱用Select写程序,他们只是习惯写诸如connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式 block,...
基本socket编程知识,包括: socket地址结构、字节排序和操纵 socket相关函数的用途和使用 基本TCP socket函数概述、TCP connect/bind/listen/accept函数 TCP并发服务器/fork和exec函数 TCP客户-服务器程序...