getsockopt (取得 socket 状态)
相关函数
setsockopt
表头文件
#include
#include
定义函数
int getsockopt(int s,int level,int optname,void* optval,socklen_t* optlen);
函数说明
getsockopt() 会将参数 s 所指定的 socket 状态返回。参数 optname 代表欲取得何种选项状态,而参数 optval 则指向欲保存结果的内存地址,参数 optlen 则为该空间的大小。参数 level optname 请参考 setsockopt()
返回值
成功则返回 0 ,若有错误则返回 -1 ,错误原因存于 errno
错误代码
EBADF 参数 并非合法的 socket 处理代码
ENOTSOCK 参数 s 为一文件描述词,非 socket
ENOPROTOOPT 参数 optname 指定的选项不正确
EFAULT 参数 optval 指针指向无法存取的内存空间
范例
#include
#include
main()
{
int s,optval,optlen = sizeof(int);
if ((s = socket(AF_INET,SOCK_STREAM,0))<0)
perror(“socket”);
getsockopt(s,SOL_SOCKET,SO_TYPE,&optval,&optlen);
printf(“optval = %d/n”,optval);
close(s);
}
执行
optval = 1 /*SOCK_STREAM 的定义正是此值 */
htonl (将 32 位主机字符顺序转换成网络字符顺序)
相关函数
htons ntohl ntohs
表头文件
#include
定义函数
unsigned long int htonl(unsigned long int hostlong);
函数说明
Htonl() 用来将参数指定的 32 hostlong  转换成网络字符顺序。
返回值
返回对应的网络字符顺序。
范例
参考 getservbyport() connect()
htons (将 16 位主机字符顺序转换成网络字符顺序)
相关函数
htonl ntohl ntohs
表头文件
#include
定义函数
unsigned short int htons(unsigned short int hostshort);
函数说明
htons() 用来将参数指定的 16 hostshort 转换成网络字符顺序。
返回值
返回对应的网络字符顺序。
范例
参考 connect()
inet_addr (将网络地址转成二进制的数字)
相关函数
inet_aton inet_ntoa
表头文件
#include
#include
#include
定义函数
unsigned long int inet_addr(const char *cp);
函数说明
inet_addr() 用来将参数 cp 所指的网络地址字符串转换成网络所使用的二进制数字。网络地址字符串是以数字和点组成的字符串,例如 :“163.13.132.68”
返回值
成功则返回对应的网络二进制的数字,失败返回 -1
inet_aton (将网络地址转成网络二进制的数字)
相关函数
inet_addr inet_ntoa
表头文件
#include
#include
#include
定义函数
int inet_aton(const char * cp,struct in_addr *inp);
函数说明
inet_aton() 用来将参数 cp 所指的网络地址字符串转换成网络使用的二进制的数字,然后存于参数 inp 所指的 in_addr 结构中。
结构 in_addr 定义如下
struct in_addr {
unsigned long int s_addr;
};
返回值
成功则返回非 0 值,失败则返回 0
inet_ntoa (将网络二进制的数字转换成网络地址)
相关函数
inet_addr inet_aton
表头文件
#include
#include
#include
定义函数
char * inet_ntoa(struct in_addr in);
函数说明
inet_ntoa() 用来将参数 in 所指的网络二进制的数字转换成网络地址,然后将指向此网络地址字符串的指针返回。
返回值
成功则返回字符串指针,失败则返回 NULL
listen (等待连接)
相关函数
socket bind accept connect
表头文件
#include
定义函数
int listen(int s,int backlog);
函数说明
listen() 用来等待参数 socket 连线。参数 backlog 指定同时能处理的最大连接要求,如果连接数目达此上限则 client 端将收到 ECONNREFUSED 的错误。 Listen() 并未开始接收连线,只是设置 socket listen 模式,真正接收 client 端连线的是 accept() 。通常 listen() 会在 socket() bind() 之后调用,接着才调用 accept()
返回值
成功则返回 0 ,失败返回 -1 ,错误原因存于 errno
附加说明
listen() 只适用 SOCK_STREAM SOCK_SEQPACKET socket 类型。如果 socket AF_INET 则参数 backlog  最大值可设至 128
错误代码
EBADF 参数 sockfd 非合法 socket 处理代码
EACCESS 权限不足
EOPNOTSUPP 指定的 socket 并未支援 listen 模式。
范例
#include
#include
#include
#include
#include
 
#define PORT 1234
#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 buffer[256];
char msg[ ] =”Welcome to server!”;
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
perror(“socket”);
exit(1);
}
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);
}
if (listen(sockfd,3)<0)
{
perror(“listen”);
exit(1);
}
for (fd=0; fd
is_connected[fd]=0;
while(1)
{
FD_ZERO(&readfds);
FD_SET(sockfd,&readfds);
for (fd=0; fd
if (is_connected[fd])
FD_SET(fd,&readfds);
if (!select(MAXSOCKFD, &readfds, NULL, NULL, NULL))
continue;
for (fd=0;fd
if (FD_ISSET(fd,&readfds))
{
if (sockfd = =fd)
{
if((newsockfd = accept (sockfd,&addr,&addr_len))<0)
perror(“accept”);
write(newsockfd,msg,sizeof(msg));
is_connected[newsockfd] =1;
printf(“cnnect from %s/n”,inet_ntoa(addr.sin_addr));
}
else
{
bzero(buffer, sizeof(buffer));
if (read(fd,buffer,sizeof(buffer))<=0)
{
printf(“connect closed./n”);
is_connected[fd]=0;
close(fd);
}
else
printf(“%s”,buffer);
}
}
}
}
执行
$ ./listen
connect from 127.0.0.1
hi I am client
connected closed.