linux程序设计——套接字选项(第十五章)

现在可以改进客户程序,使它可以连接到任何有名字的主机,这次不是连接到示例服务器,而是连接到一个标准服务,这样就可以演示端口号的提取操作了.

大多数UNIX和一些linux系统都有一项标准服务daytime,它提供系统的日期和时间.客户可以连接到这个服务来查看服务器的当前日期和时间.下面就是完成这一工作的客户程序getdate.c

编写程序getdate.c

/*************************************************************************
 > File Name:    getdate.c
 > Description:  getdate.c
 > Author:       Liubingbing
 > Created Time: 2015年07月24日 星期五 20时26分04秒
 > Other:        getdate.c
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

int main(int argc, char *argv[])
{
	char *host;
	int sockfd;
	int len, result;
	struct sockaddr_in address;
	struct hostent *hostinfo;
	struct servent *servinfo;
	char buffer[128];

	if (argc == 1)
		host = "localhost";
	else
		host = argv[1];
	/* 查找主机的地址,如果找不到,就报告一条错误 */
	hostinfo = gethostbyname(host);
	if (!hostinfo) {
		fprintf(stderr, "no host: %s\n", host);
		exit(1);
	}
	/* 检查主机上是否有daytime服务 */
	servinfo = getservbyname("daytime", "tcp");
	if (!servinfo) {
		fprintf(stderr, "no daytime service\n");
		exit(1);
	}
	printf("daytime port is %d\n", ntohs(servinfo->s_port));
	/* 创建一个套接字 */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	/* 构造connect调用要使用的地址 */
	address.sin_family = AF_INET;
	address.sin_port = servinfo->s_port;
	address.sin_addr = *(struct in_addr *)*hostinfo->h_addr_list;
	len = sizeof(address);
	/* 然后建立连接并取得有关信息 */
	result = connect(sockfd, (struct sockaddr *)&address, len);
	if (result == -1) {
		perror("oops: getdate");
		exit(1);
	}
	result = read(sockfd, buffer, sizeof(buffer));
	buffer[result] = '\0';
	printf("read %d bytes: %s", result, buffer);

	close(sockfd);
	exit(0);
}

可以用getdate获取任一已知主机的日期和时间.

如果看到上面的信息,这可能是因为正在连接的计算机没有启用daytime服务.

程序解析

运行这个程序时,可以指定要连接的主机.daytime服务的端口号是通过网络数据库函数getservbyname来确定的,该函数以与返回主机信息类似的方法返回和网络服务相关的信息.程序getdate尝试连接到指定主机返回的地址列表中的第一个地址,如果成功,它就读取daytime服务返回的信息--一个表示UNIX日期和时间的服务.

15.3.2    套接字选项

可以用许多选项来控制套接字连接的行为,这些选项的数目众多,其中setsockopt函数用于控制这些选项,它的定义如下所示:

#include <sys/socket.h>
int setsockopt(int socket, int level, int option_name, const void *option_value, size_t option_len);

可以在协议层次的不同级别对选项进行设置.如果想要在套接字级别设置选项,就必须将level参数设置为SOL_SOCKET.

option_name参数指定要设置的选项,option_calue参数的额长度为option_len字节,它用于设置选项的新值,它被传递给底层协议的处理函数,并且不能被修改.

在头文件sys/socket.h中定义的套接字级别选项,如下所示:

选项            说明

SO_DEBUG        打开调试信息

SO_KEEPALIVE    通过定义传输保持存活报文来维持连接

SO_LINGER        在close调用返回之前完成传输工作

setsockopt在成功时返回0,失败时返回-1.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-03 03:47:44

linux程序设计——套接字选项(第十五章)的相关文章

Linux TCP套接字选项 之 SO_REUSEADDR &amp;&amp; SO_REUSEPORT

说明 前面从stackoverflow上找了一篇讲这两个选项的文章,文章内容很长,读到最后对Linux中的这两个选项还是有些迷茫,所以重新写一篇文章来做一个总结: 本文只总结TCP单播部分,并且只讨论该选项的bind()系统调用部分,UDP,组播,开启选项之后数据包的调度等不做讨论: man手册中对这两个套接字的描述 SO_REUSEADDR SO_REUSEADDR Indicates that the rules used in validating addresses supplied i

linux程序设计——IPC状态命令(第十四章)

14.5    IPC状态命令 虽然X/Open规范并没有定义它们,但大多数linux系统都提供了一组命令,用于从命令行上访问IPC信息以及清理游离的IPC机制.它们是ipcs和ipcrm命令,这两个命令对于开发程序非常有用. IPC机制一个让人烦恼的问题是:编写错误的程序或者因为某些原因而执行失败的程序把它的IPC资源(如消息队列中的数据)遗留在系统中,并且这些资源在程序结束后很长时间仍然在系统中游荡.这将导致对程序的新调用执行失败,因为程序期望以一个干净的系统来启动,但事实上却发现一些遗留的

linux程序设计——取消一个线程(第十二章)

12.7    取消一个线程 有时,想让一个线程能够要求还有一个线程终止,就像给它发送一个信号一样. 线程有方法能够做到这一点,与与信号处理一样.线程能够被要求终止时改变其行为. pthread_cancel是用于请求一个线程终止的函数: #inlude <pthread.h> int pthread_cancel(pthread_t thread); 这个函数提供一个线程标识符就能够发送请求来取消它. 线程能够用pthread_setcancelstate设置线程的取消状态 #include

linux程序设计——线程的属性(第十二章)

12.6    线程的属性 在前面的所有程序示例中,都在程序退出之前用pthread_join对线程再次进行同步,如果想让线程向创建它的线程返回数据就需要这样做.但有时,也有这种情况,既不需要第二个线程向主线程返回信息,也不想让主线程等待它的结束. 假设在主线程继续为用户提供服务的同时创建了第二个线程,新线程的作用是将用户正在编辑的数据文件进行备份存储.备份工作结束后,第二个线程就可以直接终止了,它没有必要再回到主线程中. 可以创建这一类型的线程,它们被称为脱离线程(detached threa

Linux就该这么学 20181011(第十五章邮件)

参考链接:https://www.linuxprobe.com. https://www.linuxprobe.com/chapter-15.html 电子邮箱系统 foxmail MUA 发送 MTA 转发 MDA 保存 Postfix vim /etc/postfix/main.cf 发送文件 :48 systemctl restart postfix yum -y install dovecot 收取邮件 vim /etc/dovecot/dovecot.conf protocols =

《Linux程序设计 第四版》之第五章的练习题

1.P168 一个完整的终端输出选择菜单的程序. #include<stdio.h> #include<sys/time.h> #include<sys/types.h> #include<sys/resource.h> #include<math.h> #include<termios.h> #include<term.h> #include<curses.h> #include<stdlib.h>

套接字选项

套接字选项,超高级货,赛车的按钮盘 getsockopt和setsockopt 原型:int getsockopt(int s,int level,int opname,void *optval,socklen_t *optlen); 原型:int setsockopt(int s,int level,int optname,const void *optval,socklen_t optlen); s为将要获取或设置的套接字描述符,可以通过socket函数获取 level为选项所在的协议层 o

LINUX TCP套接字详细配置

提高服务器的负载能力,是一个永恒的话题.在一台服务器CPU和内存资源额定有限的情况下,最大的压榨服务器的性能,是最终的目的.要提高 Linux系统下的负载能力,可以先启用Apache的Worker模式,来提高单位时间内的并发量.但是即使这么做了,当网站发展起来之后,连接数过多 的问题就会日益明显.在节省成本的情况下,可以考虑修改Linux的内核TCP/IP参数,来最大的压榨服务器的性能.当然,如果通过修改内核参数也无法 解决的负载问题,也只能考虑升级服务器了,这是硬件所限,没有办法的事. Lin

UNIX网络编程——套接字选项

http://www.educity.cn/linux/1241288.html 有时候我们需要控制套接字的行为(如修改缓冲区的大小),这个时候我们就要学习套接字选项. int getsockopt(int sockfd,int level,int optname,void *optval,socklen_t *optlen) int setsockopt(int sockfd,int level,int optname,const void *optval,socklen_t *optlen)