c(gcc)centos 7中实现的unix域套接字中的连接错误
在实现UNIX域套接字时,连接始终被拒绝: 部分服务器代码: 我已经检查了路径“/tmp/dsock”,套接字文件“dsock”在那里,但查看文件内部显示:c(gcc)centos 7中实现的unix域套接字中的连接错误,c,linux,sockets,unix,gcc,C,Linux,Sockets,Unix,Gcc,在实现UNIX域套接字时,连接始终被拒绝: 部分服务器代码: 我已经检查了路径“/tmp/dsock”,套接字文件“dsock”在那里,但查看文件内部显示: "dsock" [Permission Denied] File: ‘dsock’ Size: 0 Blocks: 0 IO Block: 4096 socket Device: 801h/2049d Inode: 1572866 Links: 1
"dsock" [Permission Denied]
File: ‘dsock’
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: 801h/2049d Inode: 1572866 Links: 1
Access: (0777/srwxrwxrwx) Uid: ( 7418/user) Gid: (25/group)
Access: 2017-08-31 17:16:29.569038461 -0600
Modify: 2017-08-31 17:16:29.569038461 -0600
Change: 2017-09-01 13:28:07.162071494 -0600
Birth: -
文件的“stat dsock”显示:
"dsock" [Permission Denied]
File: ‘dsock’
Size: 0 Blocks: 0 IO Block: 4096 socket
Device: 801h/2049d Inode: 1572866 Links: 1
Access: (0777/srwxrwxrwx) Uid: ( 7418/user) Gid: (25/group)
Access: 2017-08-31 17:16:29.569038461 -0600
Modify: 2017-08-31 17:16:29.569038461 -0600
Change: 2017-09-01 13:28:07.162071494 -0600
Birth: -
找不到错误是什么。客户端也显示类似的连接错误。这是由于UNIX域套接字文件权限问题造成的吗?您不能在侦听套接字上调用
connect
。绑定并侦听后,使用侦听套接字应该做的唯一一件事就是调用accept
(或close
,或在选择中使用其描述符)
因此,服务器应该创建套接字,bind
它的地址,listen
,然后服务器应该坐在accept
函数中(“阻塞”)。也就是说,它正在等待连接,通常是在循环中
然后(在服务器启动并等待之后),您的客户端需要创建自己的套接字并在其上调用connect
——指定服务器调用bind
时使用的相同地址。这将导致服务器中的accept
调用为实际连接到客户端的套接字返回新的套接字描述符。这是您将用于通信的send
和recv
。(还将连接客户端的套接字。)
此时,服务器中的侦听套接字仍然可以接受其他连接(每个连接都将返回自己的新的唯一套接字描述符)
尽管有可能,但无论如何,服务器连接到自己的侦听套接字端点并没有真正意义。重点是什么?现在,我已经按照Gil Hamilton的建议适当地实现了服务器和客户端代码:
服务器代码:
int main(int argc, char *argv[])
{
/* Variable Definition */
int sockfd=-1, rem_addr_size;
struct sockaddr_un remote_addr;
chdir("/");
umask(0111);
/* Get the Socket file descriptor */
memset(&remote_addr, 0, sizeof(struct sockaddr_un));
if ((sockfd = socket(AF_LOCAL,SOCK_STREAM,0)) < 0)
{
printf("ERROR: Failed to obtain Socket Descriptor ! \n");
exit(1);
}
printf("Socket created \n");
/* Fill the socket address struct */
remote_addr.sun_family = AF_LOCAL;
strncpy(remote_addr.sun_path,"/tmp/dsock", strlen("/tmp/dsock")+1);
rem_addr_size=(offsetof(struct sockaddr_un, sun_path)
+strlen(remote_addr.sun_path)+1);
unlink(remote_addr.sun_path);
if(bind(sockfd ,(struct sockaddr *)&remote_addr,rem_addr_size)<0)
{ printf("BIND ERROR \n");
close(sockfd );
exit(1);
}
printf("Bind successful to socket !! \n");
if(listen(sockfd,16)==-1)
{ perror("Listen error !! \n");
printf("Listening error \n");
exit(-1);
}
printf("Listening to the socket \n");
int msgsock;
msgsock=accept(sockfd,0,0);
char* fs_name = "ts_data.dat";
char sdbuf[LENGTH];
printf("[Client] Sending %s to the Server... ", fs_name);
FILE *fs = fopen(fs_name, "r");
if(fs == NULL)
{
printf("ERROR: File %s not found.\n", fs_name);
exit(1);
}
printf("Success file found !! \n");
bzero(sdbuf, LENGTH);
int fs_block_sz;
if (msgsock == -1)
perror("Error in accepting socket connection \n");
else
while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0)
{
if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
{
fprintf(stderr, "ERROR: Failed to send file %s. (errno =
%d)\n", fs_name, errno);
break;
}
bzero(sdbuf, LENGTH);
}
printf(" File %s to the client was Sent!\n", fs_name);
//}
close (sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
if(sock<0){
if ((sock=socket(AF_LOCAL,SOCK_STREAM,0))<0){
syslog(LOG_USER|LOG_ERR,"Could not create socket!!");
printf("Couldn't create socket \n");
exit(-1);
}
else
{
printf("Socket created \n");
}
/* Name the socket */
s_addr.sun_family = AF_LOCAL;
strncpy(s_addr.sun_path,sock_path,strlen(sock_path)+1);
s_addr_size=(offsetof(struct sockaddr_un, sun_path)
+strlen(s_addr.sun_path)+1);
/***************/
if(connect( sock,(struct sockaddr *) &s_addr,s_addr_size)==-1)
{
syslog(LOG_USER|LOG_ERR,"Could not connect, will try later");
printf("Error %d: %s\n", errno, strerror(errno));
printf("Couldn't connect to socket... will try later \n");
close(sock);
sock=-1;
}
else
{
FD_SET(sock,&active_fd_set);
printf("Socket connected \n");
}
printf("Trying again \n\n\n");
}
客户端代码:
int main(int argc, char *argv[])
{
/* Variable Definition */
int sockfd=-1, rem_addr_size;
struct sockaddr_un remote_addr;
chdir("/");
umask(0111);
/* Get the Socket file descriptor */
memset(&remote_addr, 0, sizeof(struct sockaddr_un));
if ((sockfd = socket(AF_LOCAL,SOCK_STREAM,0)) < 0)
{
printf("ERROR: Failed to obtain Socket Descriptor ! \n");
exit(1);
}
printf("Socket created \n");
/* Fill the socket address struct */
remote_addr.sun_family = AF_LOCAL;
strncpy(remote_addr.sun_path,"/tmp/dsock", strlen("/tmp/dsock")+1);
rem_addr_size=(offsetof(struct sockaddr_un, sun_path)
+strlen(remote_addr.sun_path)+1);
unlink(remote_addr.sun_path);
if(bind(sockfd ,(struct sockaddr *)&remote_addr,rem_addr_size)<0)
{ printf("BIND ERROR \n");
close(sockfd );
exit(1);
}
printf("Bind successful to socket !! \n");
if(listen(sockfd,16)==-1)
{ perror("Listen error !! \n");
printf("Listening error \n");
exit(-1);
}
printf("Listening to the socket \n");
int msgsock;
msgsock=accept(sockfd,0,0);
char* fs_name = "ts_data.dat";
char sdbuf[LENGTH];
printf("[Client] Sending %s to the Server... ", fs_name);
FILE *fs = fopen(fs_name, "r");
if(fs == NULL)
{
printf("ERROR: File %s not found.\n", fs_name);
exit(1);
}
printf("Success file found !! \n");
bzero(sdbuf, LENGTH);
int fs_block_sz;
if (msgsock == -1)
perror("Error in accepting socket connection \n");
else
while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0)
{
if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
{
fprintf(stderr, "ERROR: Failed to send file %s. (errno =
%d)\n", fs_name, errno);
break;
}
bzero(sdbuf, LENGTH);
}
printf(" File %s to the client was Sent!\n", fs_name);
//}
close (sockfd);
printf("[Client] Connection lost.\n");
return (0);
}
if(sock<0){
if ((sock=socket(AF_LOCAL,SOCK_STREAM,0))<0){
syslog(LOG_USER|LOG_ERR,"Could not create socket!!");
printf("Couldn't create socket \n");
exit(-1);
}
else
{
printf("Socket created \n");
}
/* Name the socket */
s_addr.sun_family = AF_LOCAL;
strncpy(s_addr.sun_path,sock_path,strlen(sock_path)+1);
s_addr_size=(offsetof(struct sockaddr_un, sun_path)
+strlen(s_addr.sun_path)+1);
/***************/
if(connect( sock,(struct sockaddr *) &s_addr,s_addr_size)==-1)
{
syslog(LOG_USER|LOG_ERR,"Could not connect, will try later");
printf("Error %d: %s\n", errno, strerror(errno));
printf("Couldn't connect to socket... will try later \n");
close(sock);
sock=-1;
}
else
{
FD_SET(sock,&active_fd_set);
printf("Socket connected \n");
}
printf("Trying again \n\n\n");
}
netstat-l显示处于侦听模式的服务器:
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node Path
unix 2 [ ACC ] STREAM LISTENING 3294124420 /tmp/dsock
unix 2 [ ACC ] STREAM LISTENING 3294124858 /tmp/dsock
unix 2 [ ACC ] STREAM LISTENING 32778 /var/run/nslcd/socket
unix 2 [ ACC ] STREAM LISTENING 14365 /run/systemd/journal/stdout
unix 2 [ ACC ] STREAM LISTENING 612 /var/lib/gssproxy/default.sock
在代码中也添加了错误日志,但是客户端没有连接到套接字 解决此类问题的第一步始终是查看系统返回的错误。大多数UNIX系统调用将设置errno,以便在出错时返回-1时提供特定的错误详细信息。您应该:1)包括errno.h2)使用以下命令记录详细的错误消息:printf(“错误%d:%s\n”,errno,strerror(errno));理想情况下,这应该作为常规系统调用错误检查的一部分来完成