2012-08-02 16 views
-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; 
} 
+1

将gdb附加到服务器程序,看看发生了什么。 – jman 2012-08-02 05:01:28

+0

除了在GDB中通过服务器或客户端代码进行调试外,还可以添加更多输出。例如,如果客户端连接成功,则可以将其打印到客户端和服务器中的控制台,但更重要的是,在出现_fails_和错误代码时打印输出。 – 2012-08-02 05:41:59

+1

这不是C,而是C和C++的混合。不要这样做,这是不值得的,决定要使用哪种语言并坚持下去。 – 2012-08-02 07:08:13

回答

0

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

+0

OP将指针指向'&serverAddress',以便正确初始化。 – 2012-08-02 05:39:18

1

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

strcpy (serverAddress.sun_path,"CServer"); 

然后覆盖一些任意的内存。在C++做的正确方法是

struct sockaddr_un serverAddress = { 0 }; 

一般:

  • 始终,是一如既往地初始化所有变量。不要担心效率上的一些小的改进,否则可能会带来影响。这通常是不值得的,无论如何你还不在那里。 (这里用0进行正确的初始化会让你的程序从一开始就很好地崩溃。)

  • 总是在所有警告选项上编译。

  • 不要混合C和C++。他们有微妙的差异,这是不值得的。特别是在这里你从使用C++中获益匪浅。

+0

特别喜欢“从一开始就很好地碰撞”部分。 – 2012-08-02 07:30:19

+0

我想你应该看看['sockaddr_un'](http://linux.die.net/man/7/unix)结构,'sun_path'成员是一个合适的数组。 – 2012-08-02 09:00:54

1

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

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

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

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

共享一个链接的教程,我发现 http://tkhanson.net/cgit.cgi/misc.git/plain/unixdomain/Unix_domain_sockets.html

另一种看法是,你的代码将产生僵尸(在Linux下死进程ps命令会显示已不存在的条目),因为你还没有加入僵尸处理器。

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

signal(SIGCHLD, SIG_IGN);