我正在尝试使用监视应用程序监视长时间运行的守护程序,该应用程序创建UNIX套接字并进行侦听。但是,在测试中,我发现我在应用程序中的其他线程上对系统进行的调用显示在此套接字中。
// Output from Server Test Application (just echoing from recv buffer)
# serverTest /tmp/receiver-programmer-socket
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: PING 192.168.1.51 (192.168.1.51): 56 data bytes
--- 192.168.1.51 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
MESSAGE FROM CLIENT: PING 192.168.1.52 (192.168.1.52): 56 data bytes
--- 192.168.1.52 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: PING 192.168.1.51 (192.168.1.51): 56 data bytes
--- 192.168.1.51 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
MESSAGE FROM CLIENT: PING 192.168.1.52 (192.168.1.52): 56 data bytes
--- 192.168.1.52 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
MESSAGE FROM CLIENT: test
已经创建了长时间运行的守护程序并输出到套接字(如果可用)。目前它只是每秒钟向套接字写“测试”。
// Long Running Daemon Snippet
int Monitor::write_to_socket(){
std::string string = "test";
char buffer[1024];
bzero(buffer, sizeof(buffer));
strcpy(buffer, string.c_str());
if (send(sockfd, buffer, strlen(buffer), MSG_NOSIGNAL) < 0)
{
syslog(LOG_INFO, "Error sending to socket");
close(sockfd);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
我已将一个快速服务器应用程序粘贴在一起,以测试一切正常,因此代码非常粗糙。
/* a server in the unix domain. The pathname of
the socket address is passed as an argument */
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/un.h>
#include <stdio.h>
void error(const char *);
int connection_handler(int);
int main(int argc, char *argv[])
{
// File descriptors
int sockfd, newsockfd;
// Length of address string
int servlen;
//
int n;
// Size of client address
socklen_t clilen;
// Client socket address
struct sockaddr_un cli_addr;
// Server socket address
struct sockaddr_un serv_addr;
// Character buffer
char buf[80];
// Create socket
if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
error("creating socket");
// Sets server address area to all zeros
bzero((char *)&serv_addr, sizeof(serv_addr));
// Sets server address family to local interprocess
serv_addr.sun_family = AF_UNIX;
// Sets server address path to passed in argument
strcpy(serv_addr.sun_path, argv[1]);
// Sets length of full server address
servlen = strlen(serv_addr.sun_path) + sizeof(serv_addr.sun_family);
// Bind socket at address and port (sortof)
if (bind(sockfd, (struct sockaddr *)&serv_addr, servlen) < 0)
error("binding socket");
// Start listening for requests
listen(sockfd, 5);
pid_t child;
int connection_fd;
socklen_t address_length;
while((connection_fd = accept(sockfd, (struct sockaddr *) &serv_addr, &address_length)) > -1)
{
child = fork();
if(child == 0)
{
/* now inside newly created connection handling process */
return connection_handler(connection_fd);
}
/* still inside server process */
close(connection_fd);
}
return 0;
}
int connection_handler(int connection_fd)
{
int nbytes;
char buffer[256];
while(1) {
bzero((char *)&buffer, sizeof(buffer));
// Corrected to test for correct return and buffer size
if((nbytes = recv(connection_fd, buffer, 256, 0)) > 0)
{
buffer[nbytes] = 0;
printf("MESSAGE FROM CLIENT: %s\n", buffer);
}
}
close(connection_fd);
return 0;
}
void error(const char *msg)
{
perror(msg);
exit(0);
}
我不确定如何将调用引入套接字。此应用程序中的任何其他位置都没有使用套接字。在写入或从套接字读取之前是否应该清除缓冲区?
来自strace
输出的部分。
[pid 15286] close(4) = 0
[pid 15286] accept(3, <unfinished ...>
[pid 15296] recv(4, "test", 256, 0) = 4
[pid 15296] fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
[pid 15296] mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40001000
[pid 15296] write(1, "MESSAGE FROM CLIENT: test\n", 26MESSAGE FROM CLIENT: test
) = 26
[pid 15296] recv(4, "PING 192.168.1.50 (192.168.1.50)"..., 256, 0) = 103
[pid 15296] write(1, "MESSAGE FROM CLIENT: PING 192.16"..., 124MESSAGE FROM CLIENT: PING 192.168.1.50 (192.168.1.50): 56 data bytes
64 bytes from 192.168.1.50: seq=0 ttl=64 time=2.156 ms
) = 124
[pid 15296] write(1, "\n", 1
) = 1
[pid 15296] recv(4, "\n--- 192.168.1.50 ping statistic"..., 256, 0) = 142
[pid 15296] write(1, "MESSAGE FROM CLIENT: \n--- 192.16"..., 163MESSAGE FROM CLIENT:
--- 192.168.1.50 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 2.156/2.156/2.156 ms
) = 163
[pid 15296] write(1, "\n", 1
) = 1
[pid 15296] recv(4, "PING 192.168.1.50 (192.168.1.50)"..., 256, 0) = 103
[pid 15296] write(1, "MESSAGE FROM CLIENT: PING 192.16"..., 124MESSAGE FROM CLIENT: PING 192.168.1.50 (192.168.1.50): 56 data bytes
64 bytes from 192.168.1.50: seq=0 ttl=64 time=2.063 ms
) = 124
似乎正在正确读取邮件。我将解析守护进程的strace中的输出,看它是否发现任何东西。
更新
我无法确定此问题的根源。我重写了所有系统调用以输出到/dev/null
并仍然在套接字中收到警告和错误消息。我试图切换到TCP套接字,但遇到了同样的问题。 strace
没有在套接字上显示任何会导致这些调用出现的发送或写入调用。
最终解决方案是使用telnet和ANSI控件不断重写telnet输出以屏蔽警告消息。
答案 0 :(得分:1)
问题不在于缓冲区,并且程序的其他部分正在写入缓冲区的可能性很小,因为缓冲区是在堆栈上分配的。看来这个消息是在套接字上收到的,但是对于套接字fd = 3的普通Linux来说很奇怪,你没有打开任何文件?
例如:
nbytes = recv(connection_fd, buffer, 256, 0)
buffer[nbytes] = \0;
当nbytes为256时,您正在缓冲区外写入,这可能导致分段错误。
connection_fd = accept(sockfd, (struct sockaddr *) &serv_addr, &address_length)
覆盖服务器地址,可能是cli_addr