linux c 网络编程, 常用网络函数,范例
Posted 明风的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux c 网络编程, 常用网络函数,范例相关的知识,希望对你有一定的参考价值。
hstrerror返回网络错误原因的描述字符串
相关函数:herror
表头文件:#include <netdb.h>
函数定义:const char *hstrerror(int err)
函数说明:hstrerror()用来依参数err的错误代码来查询socket错误原因的描述字符串, 然后将该字符串指针返回
返回值 :返回描述错误原因的字符串指针
范例:
/*显示错误代码0到5的错误原因描述*/
**#include <netdb.h>**
main()
int i;
for(i=0; i<6; i++)
printf("%d: %s\\n", i, hstrerror(i));
herror指印出网络错误原因信息字符串
相关函数:hstrerror
表头文件:#include <netdb.h>
函数定义:void herror(const char *s);
函数说明:herror()用来将上一个网络函数发生错误的原因输出到标准错误stderr。参数s所指的字符串会先打印出, 后面再加上错误的原因字符串。此错误原因系依照全局变量h_errno的值来决定要输出的字符串
返回值 :无
范例:参perror()
htons将16位主机字符顺序转换成网络字符顺序
相关函数:htonl, ntonl, ntohs
表头文件:#include <netinet/in.h>
函数定义:unsigned short int htons(unsigned short int hostshort)
函数说明:htons()用来将参数指定的16位hostshort转换成网络字符顺序
返回值 :返回对应的网络字符顺序
范例:参getservbyport() connect()
htonl将32位主机字符顺序转换成网络字符顺序
相关函数:htons, ntohl, ntohs
表头文件:#include <netinet/in.h>
函数定义:unsigned long int htonl(unsigned long int hostlong)
函数说明:htonl()用来将参数指定的32位hostlong转换成网络字符顺序
返回值 :返回对应的网络字符顺序
范例:参getservbyport() connect()
inet_aton将网络地址转成网络二进制的数字
相关函数:inet_addr, inet_ntoa
表头文件:#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
函数定义:int inet_aton(const char *cp, struct in_addr *inp)
函数说明:inet_aton()用来将参数cp所指的网络地址字符串转成网络所使用的二进制的数字,然后存于参数inp所指的in_addr结构中
struct in_addr
unsigned long int s_addr; //数字和点组成的字符串,如192.168.0.239
返回值 :成功则返回非0值 , 失败则返回0
inet_addr将网络地址转成网络二进制的数字
相关函数:inet_aton, inet_ntoa
表头文件:#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
函数定义:unsigned long int inet_addr(const char *cp)
函数说明:inet_addr()用来将参数cp所指的网络地址字符串转成网络所使用的二进制的数字。网络地址字符串是以数字和点组成的字符串,如192.168.0.236
返回值 : 成功则返回对应的网络二进制的数字,失败返回-1
listen等待连接
相关函数:socket, bind, accpet, connect
表头文件:#include <sys/socket.h>
函数定义:int listen(int s, int backlog)
函 数说明:listen()用来等待参数s的socket连线。参数backlog指定同时能处理的最大连接要求,如果连接数目达到此上限则client端 将收到ECONNREFUSED的错误(请参connect())。 listen()并未开始接受连线,只是设置socket为listen模式,真正接受client()端连线的是accept()。通常 listen()会在socket()、bind()之后调用,接着才调用accept()
附加说明:listen()只适用SOCK_STREAM或SOCK_SEQPACKET的socket类型.如果socket为AF_INET则参数backlog最大值可设到128
返回值 :成功则返回0, 失败则返回-1, 错误原因存于errno中
错误代码:EBADF 参数sockfd非合法socket处理代码
EACCESS 权限不足
EOPNOTSUPP 指定的socket并未支援listen模式
范例:
/*
利用socket的TCP server此程序会接收由TCP client传来的字符串并显示
TCP client范例请参connect()
*/
**
- #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
- **列表内容**
#include <arpa/inet.h>
#include <unistd.h>
#define PROT 1234 /*使用port号码*/
#define MAXSOCKFD 10 /*可同时服务的最大连线数目*/
**
main()
int sockfd, newsockfd, is_connected[MAXSOCKFD], fd;
struct sockaddr_in addr;
int addr_len =sizeof(struct sockaddr_in);
fd_set readfds;
char msg[]="Welcome to server!";
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) <0)
perror("socket");
exit(1);
/*填写sockaddr_in结构*/
hzero(&addr, sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sockfd, &addr, sizeof(addr)) <0)
perror("connect");
exit(1);
if(listen(sockfd, 3)<0)
perror("listen");
exit(1);
/*清除连线状态旗标*/
for(fd=0; fd<MAXSOCKFD; fd++)
is_connected[fd]=0;
while(1)
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
for(fd=0; fd<MAXSOCKFD; fd++)
if(is_connected[fd])
FD_SET(fd, &readfds);
if(!select(MAXSOCKFD, &readfds, NULL, NULL, NULL))
continue;
/*判断是否有新连接或新信息进来*/
for(fd=0;, fd<MAXSOCKFD; fd++)
if(FD_ISSET(fd, &readfds))
if(sockfd == fd)
/*接收新连接*/
if((newsockfd = accept(sockfd, &addr, &addr_len)) < 0 )
perror("accept");
/*将欢迎字符串传给cient*/
write(newsockfd, msg, sizeof(msg) );
is_connected(newsockfd) = 1;
printf("Connect from %s\\n", inet_ntoa(addr.sin_addr));
/*:: if(sockfd == fd)*/
else
/*接收新信息*/
bzero(buffer, sizeof(buffer));
if(read(fd, buffer, sizeof(buffer)) <=0)
/*连接已中断,清除连接状态标志*/
printf("Connection closed.\\n");
is_connected[fd]=0;
close(fd);
else
printf("%s", buffer);
/*::else- if(sockfd == fd)*/
/*:: if(FD_ISSET(fd, &readfds))*/
/*::for(fd=0;, fd<MAXSOCKFD; fd++)*/
/*::main()*/
inet_ntoa将网络二进制的数字转成网络地址
相关函数:inet_addr, inet_aton
表头文件:#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
函数定义:char *inet_ntoa(struct in_addr in)
函数说明:inet_ntoa()用来将参数in所指的网络二进制数字转成网络地址,然后将指向此网络地址字符串的指针返回
struct in_addr
unsigned long int s_addr; //以点和数字组成的IP地址
返回值 :成功则返回字符串指针, 失败则返回NULL
范例:参connect()
ntohl将32位网络字符顺序转换成主机字符顺序
相关函数:htonl, htons, ntohs
表头文件:#include <netinet/in.h>
函数定义:unsigned long int ntohl(unsigned long int netlong)
函数说明:l将32位网络字符顺序转换成主机字符顺序
返回值 :返回对应的主机字符顺序
范例 :参getservent()
ntohs将16位网络字符顺序转换成主机字符顺序
相关函数:htonl, htons, ntohl
表头文件:#include <netinet/in.h>
函数定义:unsigned short int ntohs(unsigned short int netshort)
函数说明:将16位网络字符顺序转换成主机字符顺序
返回值 :返回对应的主机字符顺序
范 例 :参getservent()
recvfrom经socket接收数据
相关函数:recv, recvmsg, send, sendto, socket
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int recvfrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen)
函 数说明:recv()用来接收远程主机经指定的socket传来的数据,并把数据存到由参数buf指向的内存空间,参数len为可接收数据的最大长度。参 数flags一般设为0, 其他参数值定义参考recv()。 参数from用来指定欲传送的网络地址,结构sockaddr请参考bind(). 参数fromlen为sockaddr的结构长度
返回值 :成功则返回接收到的字符数, 失败则返回-1, 错误原因存于errno中
错误代码:
EBADF 参数s非合法的socket处理代码
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket
EINTR 被信号所中断
EAGAIN 此动作会令进程阻断, 但参数s的socket为不可阻断
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确
范例:
/*利用socket的UDP client 此程序会连线UDP server, 并将键盘输入的字符串传送给server UDP server范例请参考sendto()*/
- #include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
- 列表内容
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 2345 /*使用的port号码*/
#define SERVER_IP "127.0.0.1" /*server的IP*/
main()
int s, len;
struct sockadd_in addr;
int addr_len = sizeof(struct sockaddr_in);
char buffer[256];
/*建立socket*/
if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
perror("socket");
exit(1);
/*填写sockaddr_in结构*/
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr=inet_addr(SERVER_IP);
while(1)
bzero(buffer, sizeof(buffer));
/*从标准输入设备取得字符串*/
len = read(STDIN_FILENO, buffer, sizeof(buffer));
/*将字符串传送给server端*/
sendto(s, buffer, len, o, &addr, addr_len);
/*接收server端返回的字符串*/
len = revfrom(s, buffer, sizeof(buffer), 0, &addr, &addr_len);
printf("receive : %s", buffer);
/*while(1)*/
/*::main()*/
recvmsg经socket接收数据
相关函数:recv, recvfrom, send, sendto, sendmsg, socket
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int recvmsg(int s, struct msgaddr *msg, unsigned int flags)
函数说明:recvmsg()用来接收远程主机经指定的socket传来的数据。
参数s为已建立好连线的socket, 如果利用UDP协议则不需经过连线操作。
参数msg指向欲连线的数据结构内容,
参数flags一般设为0,
关于结构msghdr的定义请参考sendmsg()
返回值 :成功则返回接收到的字符数,失败返回-1, 错误原因存于errno中
错误代码:参recv
范例:参recvfrom()
sendmsg经socket传送数据
相关函数:send, sendto, recv, recvfrom, recvmsg, socket
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int sendmsg(int s, const struct msghdr *msg, unsigned int flags)
函数说明:本函数用来将数据由指定的socket传给对方主机。
参数s为已建立好连接的socket
如果利用UDP协议则不需要经过连接操作
参数msg指向欲连接的数据结构内容,参数flags一般默认为0, 详细参send()
结构msghdr定义如下
struct msghdr
void *msg_name; /*Address to send to /receive from */
socklen_t msg_namelen; /*Length of address data*/
struct iovec *msg_iov; /*Vector of data to send/recieve into */
size_t msg_iovlen; /*Number of elements in the vector*/
void *msg_control; /*Ancillary data*/
size_t msg_controllen; /*Ancillary data buffer length*/
int msg_flags; /*Flags on received message*/
;
返回值 : 成功则返回实际传送出去的字符数, 失败返回-1, 错误原因存于errno中
错误代码:参recv()
范例 :参sendto()
sendto经socket传送数据
相关函数:send, sendmsg, recv, recvfrom, socket
表头文件:#include <sys/types.h>
#incude <sys/socket.h>
函数定义:int sendto(int s, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen)
函数说明:本函数用来将数据由指定的socket传给对方主机。
参数s为已建立好连接的socket,如果利用UDP协议则不需经连接操作
参数msg指向欲连线的数据内容,
参数len则为数据长度
参数flags一般设为0,详细参send()
参数to用来指定欲传送的网络 地址,结构sockaddr请参bind()
参数tolen为sockaddr结构长度
返回值 :成功则返回实际传送出去的字符数, 失败返回-1, 错误原因存于errno中
错误代码:参recv()
范例:
/*
利用socket的UDP server
此程序会接收由UDP client传来的字符串然后再传送回client
TCP client范例请参考 recvfrom()
*/
**
- #include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 2345 /*使用的PORT号码*/
**
main()
int sockfd, len;
struct sockaddr_in addr;
int addr_len=sizeof(struct sockaddr_in);
char buffer[256];
/*建立socket*/
if((sockfd = socket(AF_INET, SOCK_DGREM, 0))<0)
perror("socket");
exit(1);
/*填写sockaddr_in结构*/
bzero(&addr, sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);
addr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sockfd, &addr, sizeof(addr)) < 0)
perror("connect");
exit(1);
while(1)
/*接收client端传来的字符串*/
bzero(buffer, sizeof(buffer));
len=recvfrom(sockfd, buffer, sizeof(buffer), 0 , &addr, &addr_len);
/*显示client端的网络地址IP*/
printf("receive from %s\\n", inet_ntoa(addr.sin_addr));
/*将字串返回给client端*/
sendto(sockfd, buffer, len, 0, &addr, addr_len);
/*::while(1)*/
/*::main()*/
recv经socket接收数据
相关函数:recvfrom, recvmsg, send, sendto, socket
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int recv(int s, void *buf, int len, unsigned int flags)
函数说明:recv()用来接收远端主机经指定的socket传来的数据,并把数据存到由参数buf指向的内存空间,
参数len为可接收数据的最大长度
参数flags一般设为0,其他值设置如下:
MSG_OOB 接收以out-of-band送出的数据
MSG_PEEK 返回来的数据并不会在系统内删除,如果再调用recv()会返回相同的数据内容
MSG_WAITALL 强迫接受到len大小的数据后才能返回,除非有错误或信号产生
MSG_NOSIGNAL 此操作不愿被SIGPIPE信号中断
返回值 :成功则返回接收到的字符数,失败则返回-1, 错误原因存于errno中
错误代码:
EBADF 参数s非合法的socket处理代码
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket
EINTR 被信号所中断
EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确
范例 :参listen()
send经socket传送数据
相关函数:sendto, sendmsg, recv, recvfrom, socket
表头文件:#include <sys/types.h>
#inlcude <sys/socket.h>
函数定义:int send(int s, const void *msg, int len, unsigned int flags)
函数说明:本函数用来把数据由指定的socket传给对方主机。
参数s为已建立好连线的socket
参数msg指向欲连线的数据内容,参数len则为数据长度
参数flags一般设为0 ,详参recv
返回值 :成功则返回实际传送出去的字符数, 失败返回-1, 错误原因存于errno中 ,
错误代码:参recv
范例: 参connect()
setprotoent打开网络协议的数据文件
相关函数:getprotobyname, getprotobynumber, endprotoent
表头文件:#include <netdb.h>
函数定义:void setprotoent(int stayopen)
函数说明:setprotoent()用来打开/etc/protocols, 如果参数stayopen值为1, 则接下来的getprotobyname()或getprotobynumber()将不会自动关闭此文件
setservent打开主机网络服务的数据文件
相关函数:getservent, getservbyname, getservbyport, endservent
表头文件:#include <netdb.h>
函数定义:void setservent(int stayopen)
函数说明:本函数用来打开/etc/services如果参数stayopen值为1,则接下来的getservbyname()或getservbyport()将不会自动关闭此文件
setsockopt设置socket状态
相关函数:getsockopt
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int setsockopt(int s, int level, int optna,e, const void *optval, socklen_t optlen)
函数说明:\\本函数用来设置参数s指定的插座的状态。
参数level代表欲设置的网络层,一般高成SOL_SOCKET以存取socket层
参数optname代表欲设置的选项,有下列几种数据
SO_DEBUG 打开或关闭排错模式
SO_REUSEADDR 允许在bind()过程中本地地址可重复使用
SO_TYPE 返回socket形态(如SOCK_STREAM)
SO_ERROR 返回socket已发生的错误原因
SO_DONTROUTE 送出的数据包不要利用路由设备来传输
SO_BROADCAST 使用广播方式传送
SO_SNDBUF 设置送出的暂存区大小
SO_RCVBUF 设置接收的暂存区大小
SO_KEEPALIVE 定期确定连接是否已终止
SO_OOBINLINE 当接收到OOB(out-of-band)数据时会马上送到标准输入设备
SO_LINGER 确保数据安全且可靠的传送出去
参数optval代表欲设置的值
参数optlen则为optval的长度
附加说明:
EBADF 参数s并非合法的socket处理代码
ENOTSOCK 参数s为一文件描述词,非socket
ENOPROTOOPT 参数optname指定的选项不正确
EFAULT 参数optval指针指向无法存取的内存空间
范例:参getsockopt()
socket建立一个socket通信
相关函数:accept, bind, connect, listen
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int socket(int domain, int type, int protocol)
函数说明:socket()用来建立一个新的socket,也一是向系统注册,通知系统建立一通信端口。
参数domain指定使用何种的地址类型,完整的定义在/usr/include/bits/socket.h内,常见的定义如下
PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX进程通讯协议P
PF_INET/AF_INENT IPV4网络协议
PF_INET6/AF_INET6 IPv6网络协议
PF_IPX/AF_IPX IPX-Novell协议
PF_NETLINK/AF_NETLINK 核心用户接口装置
PF_X25/AF_X25 ITU-T X.25/ISO-8208协议
PF_AX25/AF_AX25 业余无线AX.25协议
PF_ATMPVC/AF_ATMPVC 存取原始ATM PVCs
PF_APPLETALK/AF_APPLETALK Appletalk(DDP)协议
PF_PACKET/AF_PACKET 初级封包接口
参数type有下列几种数值:
SOCK_STREAM 提供双向连续且可信赖的数据流,即TCP,支持OOB(out-of-band)机制。在所有数据传送前必须使用connect()来建立连线状态
SOCK_DGRAM 使用不连续不可信赖的数据包连接
SOCK_SEQPACKET 提供连续可信赖的数据包连接
SOCK_RAW 提供原始网络协议存取
SOCK_RDM 提供可信赖的数据包连接
SOCK_PACKET 提供和网络驱动程序直接通信
返回值 :成功则返回socket处理代码, 失败则返回-1
错误代码:
EPROTONOSUPPORT 参数domain指定的类型不支持参数type或protocol指定的协议
ENFILE 核心内存不足, 无法建立新的socket结构
EMFILE 进程文件表溢出,无法再建立新的socket
EACCESS 权限不足,无法建立参数type或protocol指定的协议
ENOBUFS/ENOMEM 内存不足
EINVAL 参数domain/type/protocol不合法
范例:参connect()
shutdown终止socket通信
相关函数:socket, connect
表头文件:#include <sys/socket.h>
函数定义:int shutdown(int s, int how)
函数说明:用来终止参数s所指定的socket连接
参数s是连接中的socket处理代码
参数how有下列几种情况:
how=0 终止读取操作
how=1 终止传送操作
how=2 终止读取及传送操作
返回值 :成功返回0, 失败返回-1, 错误原因存于errno
错误代码:
EBADF 参数s不是有效的socket处理代码
ENOTSOCK 参数s为一文件描述词,非socket
ENOTCONN 参数s指定的socket并未连接
accept接受socket连线
相关函数:socket, bind, listen, connect
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int accept(int s, struct sockaddr *addr, int *addrlen)
函数说明:accept()用来接受参数s的socket连线。
参 数s的socket必需先经bind()、listen()函数处理过,当有连线进来是accept()会返回一个新的socket处理代码,往后的数据 传送与读取就是经由新的socket处理,而原来参数s的socket能继续使用accept()来接受新的连线要求。连线成功时,参数addr所指的结 构会被系统填入远程主机的地址数据,参数addrlen为sockaddr的结构长度。
返回值 :成功则返回socket处理代码, 失败则返回-1, 错误原因存于errno中
错误代码:EBADF 参数s非合法socket处理代码
EFAULT 参数addr指针指向无法存取的内存空间
ENOSTOCK 参数s为一文件描述词,非socket
EOPNOTSUPP 指定的socket并非SOCK_STREAM
EPERM 防火墙(firewall)拒绝此连线
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
范例:请参listen()
bind对socket定位
相关函数:socket, accept, connect, listen
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
函数说明:bind()用来设置给参数sockfd的socket一个名称。此名称由参数my_addr指向一sockaddr结构, 对于不同的socket domain定义了一个通用的数据结构:
struct sockaddr
unsigned short int sa_family; /* 为调用socket()的domain参数,即AF_xxxx值 */
char sa_data[14]; /* 最多使用14个字符长度 */
;
此sockaddr结构会因使用不同的socket domain而有不同结构的定义,例如使用AF_INET domain, 其sockaddr结构定义便为:
struct socketadd_in
unsigned short int sin_family; /* 即为sa_family */
uint16_t sin_port; /* 为使用的port编号 */
struct int_addr sin_addr; /* 为IP地址 */
unsigned char sin_zero[8]; /* 未用 */
;
struct in_addr
uint32_t s_addr;
;
参数addrlen为sockaddr的结构长度
返回值 :成功则返回0, 失败则返回-1, 错误原因存于errno中
错误代码:EBADF 参数sockfd非合法socket处理代码
EACCESS 权限不足
ENOTSOCK 参数sockfd为一文件描述词,非socket
范例: 参listen()
connect建立socket连线
相关函数:socket, bind, listen
表头文件:#include <sys/types.h>
#include <sys/socket.h>
函数定义:int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
函数说明:connect()用来将参数sockfd的socket连到参数serv_addr指定的网络地址。结构sockaddr请参bind()
返回值 :成功则返回0, 失败返回-1, 错误原因存于errno中
错误代码:EBADF 参数sockfd非合法socket处理代码
EFAULT 参数serv_addr指针指向无法存取的内存空间
ENOTSOCK 参数sockfd为一文件描述词,非socket
EISCONN 参数sockfd的socket已是连线状态
ECONNREFUSED 连线要求被server端拒绝
以上是关于linux c 网络编程, 常用网络函数,范例的主要内容,如果未能解决你的问题,请参考以下文章