-1

我已经尝试在后台运行我的服务器,它显示在 ps 下,我可以看到我的服务器正在运行,但是当我尝试运行客户端时,正确的服务器应该写信给客户端说“成功连接到服务器”,但那里没有任何输出。

我的服务器代码

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>

#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
#ifndef PF_LOCAL
#define PF_LOCAL PF_UNIX
#endif

using namespace std;

int main()
{

int serverFd;
int clientFd;
int serverLen;
int clientLen;
string message;
string serverSockAddrPtr;
struct sockaddr* serverSockAddressPnt;
struct sockaddr* clientSockAddressPnt;
struct sockaddr_un serverAddress;
struct sockaddr_un clientAddress;

cout << "" << endl;
cout << "Running server program 'css' ...... " << endl;
cout << "" << endl;


// SOCKET CREATION PART - SERVER
serverFd = socket (AF_LOCAL, SOCK_STREAM, 0);

/* Set domain type */
serverAddress.sun_family = AF_LOCAL;

/* Set name */
strcpy (serverAddress.sun_path, "CServer");


/* GET SIZE OF Server Addres */
serverLen = sizeof serverAddress;
/* GET SIZE OF Client Addres */
clientLen = sizeof clientAddress;

/* Get Server Sock Address Pointer*/
serverSockAddressPnt = (struct sockaddr *) &serverAddress;
/* Get Client Sock Address Pointer*/
clientSockAddressPnt = (struct sockaddr *) &clientAddress;

/* Create file */
bind (serverFd, serverSockAddressPnt , serverLen);

/* listen for connection */
listen (serverFd,5);


cout << "" << endl;
// SOCKET CREATION END - SERVER


while(1)
{
//accept client connection
clientFd = accept(serverFd, clientSockAddressPnt, (socklen_t*)&clientLen);

if(clientFd >= 0)
{
    if(fork() == 0)
    {
        message="Successfully connected to the server";
        write(clientFd,message.c_str(),strlen(message.c_str())+1);
        close(clientFd);
        exit(0);
    }
    else
        close(clientFd);
}

}

return 0;
}

我的客户代码

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#define DEFAULT_PROTOCOL 0
#ifndef AF_LOCAL
#define AF_LOCAL AF_UNIX
#endif
#ifndef PF_LOCAL
#define PF_LOCAL PF_UNIX
#endif

using namespace std;

/* READ LINE FUNCTION*/
int readLine (int fd,char* str)
{
    int n;
    do
    {
        n = read(fd,str,1);
    }while(n>0&& *str++ != 0);
    return(n>0);
}
/* READ LINE FUNCTION END*/


/* READ SERVER FUNCTION*/
void readServer (int fd)
{
    char str[500];
    while (readLine(fd,str))
    {
        printf("%s",str);
    }
}
/* READ SERVER FUNCTION END*/




int main()
{

int clientFd,serverLen,result;
struct sockaddr_un serverAddress;
struct sockaddr* serverSockAddressPnt;

/* Get Server Sock Address Pointer*/
serverSockAddressPnt = (struct sockaddr *) &serverAddress;

/* GET SIZE OF Server Addres */
serverLen = sizeof serverAddress;

clientFd = socket (AF_LOCAL, SOCK_STREAM, DEFAULT_PROTOCOL);
serverAddress.sun_family = AF_LOCAL;
strcpy (serverAddress.sun_path,"CServer");

do
{
    // a loop to keep trying till connected.
    result=connect(clientFd,serverSockAddressPnt,serverLen);
    if(result==-1)
    {
        //wait for 1 second to retry
        sleep(1);
    }

}while(result==-1);
readServer (clientFd);
close (clientFd);
exit(0);

return 0;
}
4

3 回答 3

1

PL。正如 Joachim 建议的那样,为您的代码添加更多错误处理。问题的最可能原因是您正在绑定,但在此之前您没有删除要绑定的套接字文件(假设该文件已经存在,因为您正在试验)(即“CServer”)。

因此,即使绑定失败,但由于错误是热处理的,服务器也会启动(您可以通过 ps 命令看到它)。即使您可以看到使用 ps 运行的服务器,您的客户端也无法连接。因此,您可以通过在绑定之前取消链接(删除)套接字文件来解决此问题。

unlink("CServer");
bind (serverFd, serverSockAddressPnt , serverLen);

我希望这能解决你的问题。

分享一个教程的链接,我找到了 http://tkhanson.net/cgit.cgi/misc.git/plain/unixdomain/Unix_domain_sockets.html

另一个观察结果是您的代码将产生僵尸(Linux 中的 defunct processes ps 命令将显示已失效的条目),因为您没有添加僵尸处理程序。

我建议一个临时解决方案是 pl。在服务器程序中的套接字调用之前添加以下行(假设是 Linux)(还包括 signal.h)以忽略 SIGCHLD(子信号死亡)。僵尸将不会被看到。

signal(SIGCHLD, SIG_IGN);
于 2012-08-02T07:52:34.797 回答
1

您的serverAddress变量未初始化。我没有检查这个,但很可能serverAddress.sun_path是一个指向 的指针char,然后它只是用一个随机值初始化。这个

strcpy (serverAddress.sun_path,"CServer");

然后覆盖一些任意内存。在 C 中执行此操作的正确方法是

struct sockaddr_un serverAddress = { 0 };

一般来说:

  • 总是,是的,总是初始化所有变量。不要担心不这样做可能会带来一些小的效率改进。这通常是不值得的,无论如何你还没有到那里。(这里正确的初始化0会让你的程序从一开始就很好地崩溃。)

  • 始终在打开所有警告选项的情况下进行编译。

  • 不要混合 C 和 C++。他们有不值得的细微差别。特别是在这里,您从使用 C++ 中一无所获。

于 2012-08-02T07:18:14.137 回答
0

客户端不知道要连接到哪个服务器。你这样做struct sockaddr* serverSockAddressPnt;但这只会定义serverSockAddressPnt为指向struct sockaddr. 但它应该被初始化或分配要连接的服务器的IP地址。

于 2012-08-02T05:06:57.083 回答