- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
最近在学习APUE.2e(UNIX®环境高级编程,第二版),已经到了第16章网络IPC:套接字。当我运行程序 ruptime
(客户端)和 ruptimed
(服务器端)时,发生了一些奇怪的事情。客户端程序显示了一个客户端命令,该命令与服务器通信以获取来自系统的uptime
命令,服务器程序ruptimed
(注意'd')接收命令,执行uptime
命令并返回输出正常运行时间
到客户端。这两个程序编译成功,我将 ruptime 4000/tcp
添加到文件 /etc/service
这意味着服务 ruptime
绑定(bind)到端口 4000/TCP
。我在同一台机器 (Ubuntu 11.04) 上运行了这两个程序,并且首先运行了 ruptimed
(当然):
$ ./ruptimed
$ ./ruptime 127.0.0.1
21:35:48 up 13:06, 3 users, load average: 0.56, 0.85, 0.94
输出是我所期望的。然而,当我跑的时候:
$ ./ruptimed
$ ./ruptime 192.168.1.221
# the terminal blocks here
IP地址192.168.1.221是机器在内网的实际IP。这里出了什么问题?上网查了一下,发现/etc/init.d/
里面好像需要一个shell脚本。然后我在 /etc/init.d/
目录中添加一个名为 ruptime
的文件。在这里:
#! /bin/sh
### BEGIN INIT INFO
# Provides: ruptimed
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop:
# Short-Description: ruptime
### END INIT INFO
start()
{
echo "start ruptime"
/home/tlh1987/apue-practice/tlh-practice/ruptimed
exit 0;
}
stop()
{
killall ruptimed
echo "stop ruptime"
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "usage: $0 start|stop|restart"
exit 0;
esac
但是,它没有用,我不知道为什么。我还设置了 ufw 启用并允许 ruptime像这样:
sudo ufw allow ruptime
也没用。 ruptime
和ruptimed
的源码如下:
// the functions used in the two program
// the connect_retry() function
#include "apue.h"
#include <sys/socket.h>
#define MAXSLEEP 128
int
connect_retry(int sockfd, const struct sockaddr *addr, socklen_t alen)
{
int nsec;
for (nsec = 1; nsec <= MAXSLEEP; nsec <<= 1) {
if (connect(sockfd, addr, alen) == 0) {
return (0);
}
if (nsec <= MAXSLEEP/2)
sleep(nsec);
}
return (-1);
}
// the initserver function
#include "apue.h"
#include <errno.h>
#include <sys/socket.h>
int
initserver(int type, const struct sockaddr *addr, socklen_t alen,
int qlen)
{
int fd;
int err = 0;
if ((fd = socket(addr->sa_family, type, 0)) < 0)
return (-1);
if (bind(fd, addr, alen) < 0) {
err = errno;
goto errout;
}
if (type == SOCK_STREAM || type == SOCK_SEQPACKET) {
if (listen(fd, qlen) < 0) {
err = errno;
goto errout;
}
}
return(fd);
errout:
close(fd);
errno = err;
return (-1);
}
// the client end i.e. ruptime.c
#include "apue.h"
#include <netdb.h>
#include <errno.h>
#include <sys/socket.h>
#define MAXADDRLEN 256
#define BUFLEN 128
extern int connect_retry(int, const struct sockaddr *, socklen_t);
void
print_uptime(int sockfd)
{
int n;
char buf[BUFLEN];
while ((n = recv(sockfd, buf, BUFLEN, 0)) > 0)
write(STDOUT_FILENO, buf, n);
if (n < 0)
err_sys("recv error");
}
int
main(int argc, char *argv[])
{
struct addrinfo *ailist, *aip;
struct addrinfo hint;
int sockfd, err;
if (argc !=2 )
err_quit("usage: ruptime hostname");
hint.ai_flags = 0;
hint.ai_family = 0;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = 0;
hint.ai_addrlen = 0;
hint.ai_canonname = NULL;
hint.ai_addr = NULL;
hint.ai_next = NULL;
if ((err = getaddrinfo(argv[1], "ruptime", &hint, &ailist)) != 0)
err_quit("getaddrinfo error: %s", gai_strerror(err));
for (aip = ailist; aip != NULL; aip = aip->ai_next) {
if ((sockfd = socket(aip->ai_family, SOCK_STREAM, 0)) < 0)
err = errno;
if (connect_retry(sockfd, aip->ai_addr, aip->ai_addrlen) < 0) {
err = errno;
} else {
print_uptime(sockfd);
exit(0);
}
}
fprintf(stderr, "can't connect to %s: %s\n", argv[1],
strerror(err));
exit(1);
}
//the server end i.e. ruptimed is as follows:
#include "apue.h"
#include <netdb.h>
#include <errno.h>
#include <syslog.h>
#include <sys/socket.h>
#define BUFLEN 128
#define QLEN 10
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 256
#endif
extern int initserver(int, struct sockaddr *, socklen_t, int);
void
serve(int sockfd)
{
int clfd;
FILE *fp;
char buf[BUFLEN];
for ( ; ; ) {
clfd = accept(sockfd, NULL, NULL);
if (clfd < 0) {
syslog(LOG_ERR, "ruptimed: accept error: %s",
strerror(errno));
exit(1);
}
if ((fp = popen("/usr/bin/uptime", "r")) == NULL) {
sprintf(buf, "error: %s\n", strerror(errno));
send(clfd, buf, strlen(buf), 0);
} else {
while (fgets(buf, BUFLEN, fp) != NULL)
send(clfd, buf, strlen(buf), 0);
pclose(fp);
}
close(clfd);
}
}
int
main(int argc, char *argv[])
{
struct addrinfo *ailist, *aip;
struct addrinfo hint;
int sockfd, err, n;
char *host;
if (argc != 1)
err_quit("usage: ruptimed");
#ifdef _SC_HOST_NAME_MAX
n = sysconf(_SC_HOST_NAME_MAX);
if (n < 0)
#endif
n = HOST_NAME_MAX;
host = malloc(n);
if (host == NULL)
err_sys("malloc error");
if (gethostname(host, n) < 0)
err_sys("gethostname error");
daemonize("ruptimed");
hint.ai_flags = AI_CANONNAME;
hint.ai_family = 0;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = 0;
hint.ai_addrlen = 0;
hint.ai_canonname = NULL;
hint.ai_addr = NULL;
hint.ai_next = NULL;
if ((err = getaddrinfo(host, "ruptime", &hint, &ailist)) != 0) {
syslog(LOG_ERR, "ruptimed: getaddrinfo error: %s",
gai_strerror(err));
exit(1);
}
for (aip = ailist; aip != NULL; aip = aip->ai_next) {
if ((sockfd = initserver(SOCK_STREAM, aip->ai_addr,
aip->ai_addrlen, QLEN)) >= 0)
serve(sockfd);
exit(0);
}
exit(1);
}
有没有人可以帮忙?
命令 netstat -nap 的标题行:
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:4000 0.0.0.0:* LISTEN 2252/ruptimed
tcp 0 13033 192.168.1.221:47380 91.189.89.114:443 LAST_ACK -
tcp 74 0 192.168.1.221:43914 91.189.89.76:443 ESTABLISHED 1846/python
tcp 0 0 127.0.0.1:4000 127.0.0.1:56344 TIME_WAIT -
tcp 0 1 192.168.1.221:35442 192.168.1.89:24800 SYN_SENT 1478/synergyc
tcp 0 0 192.168.1.221:34957 74.125.71.125:5222 ESTABLISHED 1618/chrome
tcp 0 0 192.168.1.221:57795 203.208.46.163:443 ESTABLISHED 1618/chrome
tcp6 0 0 :::22 :::* LISTEN -
第三条记录是我的服务运行时间。有什么问题吗?我不太了解它的意思。
最佳答案
我不是 C 专家,但我知道一件事:您的守护程序可能只绑定(bind)到一个地址/接口(interface),并且只接受来自它的连接。
使用 netstat -nap
检查守护进程绑定(bind)到哪个地址。
如果它正在监听 0.0.0.0
,那么它正在接受来自每个接口(interface)的连接,包括本地主机。
如果它正在监听 127.0.0.1
,它将只接受来自本地主机的消息。
我打赌它只绑定(bind)到 127.0.0.1
,这就是为什么你不能连接到任何其他地址。
关于c - Linux 守护进程 localhost 有效,但实际 IP 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10074385/
我有一个接受以下参数的函数: int setvalue(void (*)(void *)); 为了满足参数:void (*)(void *),我创建了这样一个函数: static void *
我有以下代码: typedef void VOID; int f(void); int g(VOID); 在 C 中编译得很好(在 Fedora 10 上使用 gcc 4.3.2)。与 C++ 编译的
这个问题已经有答案了: Is f(void) deprecated in modern C and C++? [duplicate] (6 个回答) 已关闭 7 年前。 B.A.T.M.A.N./A.
我在 ASP.NET Core 3.1 项目上有以下 Identity Server 4 配置: services .AddIdentityServer(y => { y.Events.R
我们有一个 O365 租户,一切都是开箱即用的。租户放置在德国云中,而不是全局 (office.de) 中。我们还开发了一个 Office 插件,使用 OAuth 2.0 授权访问共享点。首先,我们向
我有一个如下所示的路由 routes.MapRoute( name: "Default", url: "{controller}/{action}/{i
我正在尝试使用 OAuth2.0 访问 google 文档。我已经从 Google API 控制台获取了客户端 ID 和 key 。但是当我运行这段代码时,我收到了异常。如果我遗漏了什么,有人可以建议
此代码有效: let mut b: Vec = Vec::with_capacity(a.len()); for val in a.iter() { b.push(val); } 此代码不起作
使用 client_credintials 授权类型请求 EWS oauth2 v2.0 的访问 token 时出现错误。 https://login.microsoftonline.com/tena
我通过 Java 应用程序使用 Google 电子表格时遇到了问题。我创建了应用程序,该应用程序运行了 1 年多,没有任何问题,我什至在 Create Spreadsheet using Google
如何创建 匹配所有无效 Base64 字符的正则表达式?我在堆栈上找到了 [^a-zA-Z0-9+/=\n\r].*$ 但是当我尝试时我得到了带有 - 符号的结果字符串.我根本不知道正则表达式,任何人
我从 Gitlab CI/CD Pipelines 获得错误信息:yaml invalid。问题是由 .gitlab-ci.yml 脚本的第五行引起的: - 'ssh deployer@gita
我有 3 个数据源,设置如下: @Configuration @Component public class DataSourceConfig { @Bean("foo") @Conf
你好,我想用bulkCreate ex 插入数据: [ { "typeId": 5, "devEui": "0094E796CBFCFEF9", "application_name": "Pressu
UIApplicationExitsOnSuspend 不会强制我的应用程序退出。我已经清理过目标、删除了应用程序、重建并重新安装了很多次。 我确实需要退出我的应用程序。 最佳答案 您是否链接了 SD
在 iPhone 配置门户上,显示我的 iPhone 团队配置配置文件无效。有一个“由 Xcode 管理”文本。 “续订”按钮被禁用。 我该如何解决这个问题?谢谢 最佳答案 使用 Xcode 3.2.
好的,所以今天我用我们的“实时”数据库中的新信息更新了我的数据库……从那时起,我的一个表格就出现了问题。如果您需要任何代码,请告诉我,我将对其进行编辑并发布所需的代码... 我有一个报告表格,其中有一
我有一个结构体,其中有一个元素表示为 void (*func)(); 我知道 void 指针通常用于函数指针,但我似乎无法定义该函数。我不断收到取消引用指向不完整类型的指针。我用谷歌搜索了一下但没有结
我正在尝试使用 Coldfusion 9 从 ning 网络获取凭证,所以首先这是测试 api 的 curl 语法: curl -k https://external.ningapis.com/xn/
这个问题已经有答案了: Does C have references? (2 个回答) 已关闭 4 年前。 我正在学习 C 语言引用,这是我的代码: #include int main(void)
我是一名优秀的程序员,十分优秀!