- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在编写一个程序员用户友好的 inetd 样式包装器,但全部在 C 中。这个守护进程将一直运行,而且必须很快,所以 inetd 不是一个选项。而且,我希望我下面的代码对其他人有用---事实上,作为一个新手,我已经多次觉得它不存在很奇怪。 (我写我的代码是因为我之前的问题是否存在于某些图书馆违反了指导方针。)
我还有几个问题:
我不知道如何获取xxx.xxx.xxx.xxx形式的clientip。在 tcpserver_clientip() 中,这需要写入 c->ipaddress,然后由我的 tcpserver_clientip() 函数返回。我也很想知道如何反向查找客户端 DNS 名称 tcpserver_clientname(),但这是改天的事。
我不知道如何关闭本地端口,以便在有序程序终止时立即释放。现在,该端口在几秒钟后再次可用。依靠进程死亡来释放资源对我来说似乎是一个错误。 setsockopt 这样做似乎也很奇怪——我想在有效退出时关闭它,而不是在打开它时设置选项。
如果不使用 tcpserver_clientwrite(),我希望 listener() 可以打印到标准输出;而不是使用 tcpserver_clientread(),listener() 可以从标准输入读取。这在 linux(和 C)中是否可能而不会损失很大的速度?我不相信是这样。也就是说,我不相信可以将 stdin/stdout 挂接到套接字 recvfrom 和 sendto 中。但与其猜测,我想问。
有谁知道为什么 sigaction() 失败,而 signal() 在哪里工作? (为了保护我免受僵尸 child 的伤害?)这是在 linux gcc 下。 sigaction和signal的原型(prototype)好像不一样。
对于 tcp(不是 udp),是否有像这样无需 fork 即可运行的示例程序?我只见过这种带有fork的代码。据推测,读取器/写入器功能必须携带一个结构,以说明特定输入/输出刚刚来自/将要到达的许多客户端中的哪一个。据推测,避免 fork 可以节省更多时间。
此外,如果有人注意到安全漏洞或其他错误,请告诉我。
所以这是我的布局和目的:
/*
NAME
tcpserver.h
DESCRIPTION
a high-level library implementation of a tcp server, with an inetd-like
ease-of-use. the library takes care of forking, reaping, etc. The focus
right now are clean text connections ('\0' terminated, but overflow safe).
BUGS
USER INTERFACE
the user calls the tcpserver function with a callback, the listener():
*/
static int tcpserver(const int port, const int msgmaxlen, int (*listener)(void *));
static int tcpserver_verbose(const int port, const int msgmaxlen, int (*listener)(void *));
/*
the listener() has access to the following functions:
*/
static int tcpserver_clientwrite( const void *, const char *msg );
static char *tcpserver_clientread( const void * );
static char *tcpserver_clientip( void * ); // this will store inside the structure, so its volatile
static int tcpserver_clientport( const void *);
static const char *tcpserver_version= "tcpserver.h 0.1";
这是我想如何使用它的示例:
USE EXAMPLE
#include <stdio.h>
#include "tcpserver.h"
int listener( void *c ) {
printf("listener %d> Hello IP='%s' on port %d\n", getpid(),
tcpserver_clientip(c), tcpserver_clientport(c));
int terminate=0;
do {
char *msgin= tcpserver_clientread( c );
printf("listener %d r> '%s'\n", getpid(), msgin);
tcpserver_clientwrite( c, msgin );
printf("listener %d w> '%s'\n", getpid(), msgin);
fflush(stdout);
terminate= (((strncmp(msgin, "quit", 4)==0)&&(msgin[4]=='\r'))
||((strncmp(msgin, "bye", 3)==0)&&(msgin[3]=='\r')));
} while (!terminate);
printf("\nlistener %d> **** listener requested orderly termination ****\n", getpid());
exit(EXIT_SUCCESS);
}
int main(int argc, char *argv[]) {
const int PORT= (argc>=2) ? atoi(argv[1]) : (32001);
const int MAXMSGLEN=1024;
printf("Parent %d. version %s\n", getpid(), tcpserver_version);
return tcpserver( PORT, MAXMSGLEN, &listener );
}
这里是代码本身,也被塞进同一个 .h 文件中:
/****************************************************************/
#ifndef INETVERBOSE
#define INETVERBOSE 1
#endif
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/socket.h>
/********************************************************************************************************************************
* Storage for each client connection
****************************************************************/
#define MAXIPSTRLEN
struct tcpserver_clientconnection {
struct sockaddr_in cliaddr; // Socket Library
int connfd; // Socket Library
socklen_t clilen; // Socket Library
// read/write to client
char *msgbuf; // the buffer for a single longest message
int msgmaxlen; // its maximum length
int verbose; // makes debugging easier
// write by tcpserver, read-only to client
unsigned int port;
char ipaddress[MAXIPSTRLEN];
};
/********************************************************************************************************************************
* The Actual Server
****************************************************************/
static int _tcpserver(const int port, const int msgmaxlen, int (*listener)(void *c), const int verbose) {
void die(const char *s) { fprintf(stderr, "tcpserver.h death: %s : ", s); perror(""); exit(EXIT_FAILURE); }
const int parentpid= getpid();
const int listenfd=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(port);
if (verbose) fprintf(stderr, "[parent %d] ---------------- Listening on Port %d\n", parentpid, port);
if (bind(listenfd,(struct sockaddr *)&(servaddr),sizeof(servaddr)))
die("Sorry, we could not bind to the socket");
// safety --- reap all children
signal(SIGCHLD, SIG_IGN); // sigaction(SIGCHLD, SA_NOCLDWAIT)
if (listen(listenfd,1024)) die("Cannot listen to you.");
for(;;) {
// collect what we need to pass
struct tcpserver_clientconnection c;
c.port= port;
c.clilen=sizeof(c.cliaddr);
c.connfd = accept(listenfd,(struct sockaddr *)&(c.cliaddr),&(c.clilen));
if (verbose) fprintf(stderr, "[parent %d] incoming connection ", parentpid);
pid_t childpid;
if ((childpid = fork()) == 0) {
close(listenfd); // the child can close its listenfd connection
if (verbose) { fprintf(stderr, "[Spawned Child Process %d for connection]\n", getpid()); }
c.verbose= verbose;
c.msgmaxlen= msgmaxlen;
c.msgbuf= (char *) calloc( msgmaxlen, sizeof(char) );
if (!c.msgbuf) die("cannot allocate memory to message buffer");
listener(&c);
free(c.msgbuf);
}
int status;
waitpid(childpid, &status, 0);
if (verbose) fprintf(stderr, "[Parent Asynch: Child %d was stopped with return value %d]\n", childpid, status);
close(c.connfd); // release the connection
}
if (verbose) fprintf(stderr, "[%d] Main Program Bye", parentpid);
return EXIT_SUCCESS;
}
static inline int tcpserver_verbose(const int port, const int msgmaxlen, int (*listener)(void *c)) {
return _tcpserver(port, msgmaxlen, listener, 1);
}
static inline int tcpserver(const int port, const int msgmaxlen, int (*listener)(void *c)) {
return _tcpserver(port, msgmaxlen, listener, 0);
}
/********************************************************************************************************************************
* Listener (Client) Access Functions
****************************************************************/
static char *tcpserver_clientip(void *v) {
struct tcpserver_clientconnection *c= (struct tcpserver_clientconnection *)v;
const char *peer_addr(int sockfd, char *ipnamedest, size_t ipnamedestsiz) {
struct sockaddr_in adr_inet;
unsigned int len_inet = sizeof(adr_inet);
int z = getpeername(sockfd, (struct sockaddr *)&adr_inet, &len_inet);
if ( z == -1 ) return NULL; /* Failed */
z = snprintf(ipnamedest, ipnamedestsiz, "%s:%d", inet_ntoa(adr_inet.sin_addr), (unsigned)ntohs(adr_inet.sin_port));
if ( z == -1 ) return NULL; /* Ipnamedestfer too small */
return ipnamedest;
}
strcpy(c->ipaddress, "unknown");
//peer_addr( listenfd, c->ipaddress, MAXIPSTRLEN );
if (c->verbose) fprintf(stderr, "IP=%s\n", c->ipaddress);
return c->ipaddress;
}
static int tcpserver_clientport( const void *v ) {
struct tcpserver_clientconnection *c= (struct tcpserver_clientconnection *)v;
return c->port;
}
static char *tcpserver_clientread( const void *v ) {
struct tcpserver_clientconnection *c= (struct tcpserver_clientconnection *)v;
if (!c->msgbuf) perror("internal error: NULL msgbuf");
int rc= recvfrom(c->connfd, c->msgbuf, c->msgmaxlen, 0, (struct sockaddr *)&(c->cliaddr), &(c->clilen));
if (rc<0) { perror("what is wrong with you?\n"); return NULL; }
c->msgbuf[c->msgmaxlen -1]='\0'; // for safety...always
if (rc>0) c->msgbuf[rc]='\0'; // for safety...always
if (c->verbose) fprintf(stderr, "clientread> '%s'\n", c->msgbuf);
return c->msgbuf;
}
static int tcpserver_clientwrite( const void *v, const char *msg ) {
struct tcpserver_clientconnection *c= (struct tcpserver_clientconnection *)v;
if (!msg) perror("why would you want to write a NULL msg??");
int n=strlen(msg);
if (n==(-1)) n= strlen(c->msgbuf); // -1 means textmode
if (n > (c->msgmaxlen)) n= c->msgmaxlen;
if (c->verbose) fprintf(stderr, "clientwriting> '%s'\n", c->msgbuf);
sendto(c->connfd, c->msgbuf, n, 0, (struct sockaddr *)&(c->cliaddr),sizeof((c->cliaddr)));
if (c->verbose) fprintf(stderr, "clientwritten> '%s'\n", c->msgbuf);
return n;
}
最佳答案
I do not know how to obtain the clientip in xxx.xxx.xxx.xxx form.
您不需要那种形式的它。您需要它的二进制形式,如 sockaddr_in。其他任何东西都只是装饰品。
I do not know how to close the local port
使用 close()。
I would prefer if, instead of using tcpserver_clientwrite(), listener() could print to stdout; and instead of using tcpserver_clientread(), listener() could read from stdin. Is this possible in linux (and C)
是的。
without losing a great deal of speed?
不会损失任何速度。我不知道你为什么不这么想。并不是说这是个好主意。
您的代码并不像您想象的那么出色。例如,它一次只处理一个客户端,而不是并行处理所有客户端,因为您在启动后等待每个 child 。你也在等待 child 在的 child ,这是一个错误。您的消息发送/接收 API 与 send() 和 recv() 相比没有任何改进。
关于C tcp socket magic : clientip, 关闭端口,重新连接标准输入/标准输出,sigaction,速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19342588/
我想知道两者都可以 UnicastRemoteObject.exportObject(Remote,portNo) & LocateRegistry.createRegistry(portNo); p
我有一个运行 tomcat 8.0.23 和 apache httpd 服务器的 vps。在 tomcat 中我有 3 个项目让我们用下面的名字来调用它们: /firstpro /secondpro
我试图将非 SSL 端口 8080 上的流量重定向到 SSL 端口 8443(在 Jboss 4.2.3.GA 版本上),但它不起作用。当我在此端口上访问我的 web 应用程序时,它会停留在该端口上并
跟进: Possible to query the native inbox of a mobile from J2ME? 我怎么知道Kannel将 SMS 发送到 native 收件箱端口(我想是端
我想用 python 开发一个代码,它将在本地主机中打开一个端口并将日志发送到该端口。日志只是 python 文件的命令输出。 喜欢: hello.py i = 0 while True:
我的 tomcat 在我的 linux 机器上独立运行在端口 7778 上。我已经将 apache 配置为在端口 443 上的 ssl 上运行。 我的 httpd.conf 如下: Liste
我正在使用 React Native 作为我想要部署到 iOS 和 Android 的头像生成器。我正在为我的服务器使用 Express,它使用 localhost:3000,react native
我正在使用主板(MSI Gaming主板)和两个支持NIC卡的e1000e驱动程序构建自定义操作系统。我想使用NIC卡中的端口而不是板载端口。 为了禁用板载端口,我尝试使用 70-persistanc
我目前使用的是xampp 1.7.0,我的php版本是5.2.8 我将我的 php.ini 文件更改为: [mail function] ; For Win32 only. SMTP = smtp.g
我有以下代码来配置 Jetty 服务器: @Configuration public class RedirectHttpToHttpsOnJetty2Config { @Bean p
我使用 Ubuntu 使用 Certbot 生成了一个 SSL。这已经自动更新了我的 Nginx 配置文件并添加了一个额外的监听端口。我担心我是否只需要监听一个端口(80 或 443)而不是两个端口,
我被困在一个点,我必须调用 pentaho API 来验证来自 reactJS 应用程序的用户。两者都在我的本地机器上。到目前为止我尝试过的事情: a) 在 reactJS 配置文件 - packag
我的 native 项目在 android 模拟器上运行 但是每当我尝试将我的项目与我的 android 设备连接时,就会出现上述错误。 注意:我的手机和笔记本电脑使用相同的 wifi 连接。 请帮我
我正在运行 Elasticsearch 服务器。除了 9200/9300 端口外,Elasticsearch 还开放了很多端口,如下所示。 elasticsearch-service-x64.exe
<portType> 元素是最重要的 WSDL 元素 <portType>可描述一个 web service、可被执行的操作,以及相关的消息 我们可以把 <portT
Stack Overflow 的其他地方有一个关于让 Icecast 出现在端口 80 上的问题,我已经阅读了该问题,但仍然无法让我的服务器在端口 80 上工作。 我的 icecast.xml 有这些
如果这是一个简单的问题,我很抱歉,我对这种事情不熟悉。 我正在尝试确定我的代理服务器 ip 和端口号,以便使用 google 日历同步程序。我使用谷歌浏览器下载了 proxy.pac 文件。最后一行是
我想知道 cassnadra 是否对所有 JMX 连接/节点间通信使用 7199 端口?与早期版本一样,7199 仅用于初始握手,但后来它使用随机选择 1024-65355 端口之间的任何端口。 谢谢
在docker hub中,有一个容器,该容器在启动时会默认打开9000端口。可以通过传递环境变量server__port来覆盖该端口。 我正在尝试在dockerfile中传递Heroku $ PORT
我已经在互联网上公开的虚拟机中安装了 docker。我已经在 VM 的 docker 容器中安装了 mongodb。Mongodb 正在监听 27017港口。 我已经使用以下步骤安装 docker
我是一名优秀的程序员,十分优秀!