close() 和 shutdown()--Get outta my face!
你已经整天都在发送 (send()) 和接收 (recv()) 数据了,现在你准备 关闭你的套接口描述符了。这很简单,你可以使用一般的 Unix 文件描述符的 close() 函 数:
close(sockfd);
他将防止套接口上更多的数据的读写。任何在另一端读写套接口的企图都将返回错误信息。
如果你想在如何关闭套接口上有多一点的控制,你可以使用函数 shutdown()。他能够让 你将一定方向的通讯或者双向的通讯(就象 close() 一样)关闭,你可以使用:
int shutdown(int sockfd, int how);
sockfd 是你想要关闭的套接口文件描述复。how 的值是下面的其中之一:
0 - Further receives are disallowed
1 - Further sends are disallowed
2 - Further sends and receives are disallowed (和 close() 一样
shutdown() 成功时返回 0,失败时返回 -1(同时设置 errno。)
如果在无连接的数据报套接口中使用 shutdown(),那么只不过是让 send() 和 recv() 不能使用(记得你在数据报套接口中使用了 connect 后是可以 使用他们的吗?)
--------------------------------------------------------------------------------
getpeername()--Who are you?
这个函数太简单了。
他太简单了,以至我都不想单列一章。但是我还是这样做了。
函数 getpeername() 告诉你在连接的流式套接口上谁在另外一边。函数是这样的:
#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr *addr, int *addrlen);
sockfd 是连接的流式套接口的描述符。addr 是一个指向结构 struct sockaddr (或者是 struct sockaddr_in) 的指针,他保存着 连接的另一边的信息。addrlen 是一个 int 型的指针,他初始化为 sizeof(struct sockaddr)。
函数在错误的时候返回 -1,设置相应的 errno。
一旦你获得他们的地址,你可以使用 inet_ntoa() 或者 gethostbyaddr() 来打印或者获得更多的信息。但是你不能得到他的帐号。(如果他运行着愚蠢的守护进程,这是 可能的,但是他的讨论已经超出了本文的范围,请参考 RFC-1413 以获得更多的信息。)
-------------------------------------------------------------------------------
gethostname()--Who am I?
甚至比 getpeername() 还简单的函数是 gethostname()。他返回你程序 所运行的机器的主机名字。然后你可以使用 gethostbyname() 以获得你的机器的 IP 地址。
下面是定义:
#include <unistd.h>
int gethostname(char *hostname, size_t size);
参数很简单:hostname 是一个字符数组指针,他将在函数返回时保存 主机名。size 是 hostname 数组的字节长度。
函数调用成功时返回 0,失败时返回 -1,并设置 errno。
--------------------------------------------------------------------------------
DNS--You say "whitehouse.gov", I say "198.137.240.100"
如果你不知道 DNS 的意思,那么我告诉你,他代表"域名服务 (Domain Name Service)"。他主要的功能是:你给他一个容易记忆的某站点的地址,他给你 IP 地址(然后你就可以 使用 bind(), connect(), sendto() 或者其他函数。)当一个人 输入:
$ telnet whitehouse.gov
telnet 能知道他将连接 (connect()) 到 "198.137.240.100"。
但是这是如何工作的呢? 你可以调用函数 gethostbyname():
#include <netdb.h>
struct hostent *gethostbyname(const char *name);
很明白的是,他返回一个指向 struct hostent 的指针。这个数据结构是 这样的:
struct hostent {
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
};
#define h_addr h_addr_list[0]
这里是这个数据结构的详细资料: struct hostent:
h_name - Official name of the host.
h_aliases - A NULL-terminated array of alternate names for the host.
h_addrtype - The type of address being returned; usually AF_INET.
h_length - The length of the address in bytes.
h_addr_list - A zero-terminated array of network addresses for the host. Host addresses are in Network Byte Order.
h_addr - The first address in h_addr_list.
gethostbyname() 成功时返回一个指向 struct hostent 的 指针,或者是个空 (NULL) 指针。(但是和以前不同,errno 不设置,h_errno 设置错误信息。请看下面的 herror()。)
但是如何使用呢? 这个函数可不象他看上去那么难用。
这里是个例子:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
struct hostent *h;
if (argc != 2) { /* error check the command line */
fprintf(stderr,"usage: getip address\n");
exit(1);
}
if ((h=gethostbyname(argv[1])) == NULL) { /* get the host info */
herror("gethostbyname");
exit(1);
}
printf("Host name : %s\n", h->h_name);
printf("IP Address : %s\n",inet_ntoa(*((struct in_addr *)h->h_addr)));
return 0;
}
在使用 gethostbyname() 的时候,你不能用 perror() 打印错误信息(因 为 errno 没有使用),你应该调用 herror()。
相当简单,你只是传递一个保存机器名的自负串(例如 "whitehouse.gov") 给 gethostbyname(),然后从返回的数据结构 struct hostent 中 收集信息。
唯一让人迷惑的是打印 IP 地址信息。h->h_addr 是一个 char *, 但是 inet_ntoa() 需要的是 struct in_addr。因此,我 转换 h->h_addr 成 struct in_addr *,然后得到数据。

Linux/Unix网络编程指南(Socket 编程)—(10)
作者:转载自:更新时间:2009-8-2
- 视频教程在线观看
- Visual Basic从入门到精通视频教程
- 李天生SQL2008数据库视频教程
- 李天生二级VF考试视频教程
- 李天生Java软件开发高级视频教程
- 李天生Java软件开发高级教程
- C++从入门到精通视频教程
- 鹏哥C#语言从入门到高级视频教程
- 李天生JavaScript+JQuery视频教程
- C#教程:路径中的空格问题
- Java教程:JAVA时间格式化处理
- Java教程:Java终止函数详解
- Java教程:内存泄漏
- Java教程:IO流之对象流应用
- Java教程:垃圾回收算法4
- Java教程:垃圾回收算法3
- Java教程:垃圾回收算法2
- Java教程:垃圾回收算法 1
- C#教程:16进制转换10进制
- C#教程:账号加密算法
- C#教程:C#运算符重载
- C#教程:获得时间段
- VB.net教程:编写文字加解密程序
- Java教程:处理数据库超时与死锁
- C#教程:借助API实现黑盒自动化测试
- C#教程:分析Dialog控件
- C#教程:调用外部程序
- C#教程:读取数据库返回泛型
- C#教程:字符串截取方法
- C#教程:删除list中的元素
- C#教程:附加数据库
- C#教程:保留小数位
- Delphi教程:数据采集与串口通信测
- JAVA教程:多线程
- VB教程:实例问题一则
- vb教程:实现多线程!
- vb教程:实现JPEG数据压缩
- VB教程:VB中调用VC++开发的DLL
- JAVA教程:UDP数据广播的局域网络会
- C语言教程:C 程序开发经典实例之7
- C语言教程:实现的闹钟程序
- 如何利用用C语言来解决鬼谷算题
- C语言教程:C 程序开发经典实例之一
- C语言教程:C 程序开发经典实例之2
- C语言教程:C 程序开发经典实例之3
- C语言教程:C 程序开发经典实例之4
- C语言教程:C 程序开发经典实例之6
- C语言教程:C 程序开发经典实例之8
- C语言教程:C 程序开发经典实例之9
- C语言教程:C 程序开发经典实例之1
- C语言教程:C语言程序设计技巧
- C语言教程:C 程序开发经典实例之5
- C语言教程:入门基础
- 如何在VB.net中应用HOOK(二)
- 如何在VB.NET中取得计电脑的硬件信
- C语言教程:写好C程序的10条秘籍
- C语言教程:入门基础2
- C语言教程:C语言入门
- VB.NET实例:删除文件时出错
- VB.NET实例:求一个因式分解的程序
- 关于MDI多文档编辑器的问题
- 如何产生不同的随机数?
- VB第三方控件实现XP资源管理器垂直
- VB第三方控件实现XP资源管理器垂直
- Delphi基础教程:开发分隔线组件
- Delphi基础教程:在程序中调用自己
- Delphi基础教程:面向组件的系统开
- Delphi基础教程:创建VCL 构件及开
- Delphi基础教程:编写ASP中的Activ