$./server1 $$./clIEnt1 MESSAGE FROM SERVER: hello from a clIEnt
我希望服务器从客户端和客户端打印消息hello以从服务器打印hello.
我的 *** 作系统和编译器如下:
$uname -a linux temeraire 2.6.37.6-smp #2 SMP Sat Apr 9 23:39:07 CDT 2011 i686 Intel(R) Xeon(R) cpu E3110 @ 3.00GHz GenuineIntel GNU/linux$gcc -vReading specs from /usr/lib/gcc/i486-@R_381_4046@-linux/4.5.2/specsColLECT_GCC=gccColLECT_LTO_WRAPPER=/usr/libexec/gcc/i486-@R_381_4046@-linux/4.5.2/lto-wrapperTarget: i486-@R_381_4046@-linuxConfigured with: ../gcc-4.5.2/configure --prefix=/usr --libdir=/usr/lib --mandir=/usr/man --infodir=/usr/info --enable-shared --enable-bootstrap --enable-languages=ada,c,c++,fortran,java,objc,lto --enable-threads=posix --enable-checking=release --with-system-zlib --with-python-dir=/lib/python2.6/site-packages --disable-@R_837_4035@-exceptions --enable-__cxa_atexit --enable-libssp --enable-lto --with-gnu-ld --verbose --with-arch=i486 --target=i486-@R_381_4046@-linux --build=i486-@R_381_4046@-linux --host=i486-@R_381_4046@-linuxThread model: posixgcc version 4.5.2 (GCC)
server.c:
#include <stdio.h>#include <sys/socket.h>#include <sys/un.h>#include <sys/types.h>#include <unistd.h>#include <string.h>int connection_handler(int connection_fd){ int nbytes; char buffer[256]; nbytes = read(connection_fd,buffer,256); buffer[nbytes] = 0; printf("MESSAGE FROM CLIENT: %s\n",buffer); nbytes = snprintf(buffer,256,"hello from the server"); write(connection_fd,nbytes); close(connection_fd); return 0;}int main(voID){ struct sockaddr_un address; int socket_fd,connection_fd; socklen_t address_length; pID_t child; socket_fd = socket(PF_UNIX,SOCK_STREAM,0); if(socket_fd < 0) { printf("socket() Failed\n"); return 1; } unlink("./demo_socket"); /* start with a clean address structure */ memset(&address,sizeof(struct sockaddr_un)); address.sun_family = AF_UNIX; snprintf(address.sun_path,UNIX_PATH_MAX,"./demo_socket"); if(bind(socket_fd,(struct sockaddr *) &address,sizeof(struct sockaddr_un)) != 0) { printf("bind() Failed\n"); return 1; } if(Listen(socket_fd,5) != 0) { printf("Listen() Failed\n"); return 1; } while((connection_fd = accept(socket_fd,&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); } close(socket_fd); unlink("./demo_socket"); return 0;}
clIEnt.c:
#include <stdio.h>#include <sys/socket.h>#include <sys/un.h>#include <unistd.h>#include <string.h>int main(voID){ struct sockaddr_un address; int socket_fd,nbytes; char buffer[256]; socket_fd = socket(PF_UNIX,0); if(socket_fd < 0) { printf("socket() Failed\n"); return 1; } /* start with a clean address structure */ memset(&address,"./demo_socket"); if(connect(socket_fd,sizeof(struct sockaddr_un)) != 0) { printf("connect() Failed\n"); return 1; } nbytes = snprintf(buffer,"hello from a clIEnt"); write(socket_fd,nbytes); nbytes = read(socket_fd,256); buffer[nbytes] = 0; printf("MESSAGE FROM SERVER: %s\n",buffer); close(socket_fd); return 0;}解决方法 作为 Dietrich Epp mentioned,您无法初始化在服务器代码中传递给accept的address_length参数.根据 man page,这个参数既是输入参数又是输出参数:在输入时,你告诉它你的地址结构有多大(这样它就知道在告诉你连接客户端的地址时不要写出超出界限的内存),在输出上它告诉你实际上有多大的地址.
要解决此问题,请在调用accept之前将address_length初始化为sizeof(地址).您还应该为每个要接受的调用执行此 *** 作,因为可以修改变量.例如:
while(1){ address_length = sizeof(address); if((connection_fd = accept(...,&address_length)) == -1) { printf("accept error: %s\n",strerror(errno)); break; } ...}
我能够重现你的问题是显式地将address_length初始化为无效的值(sockaddr_t)-1,这导致接受失败并出现EINVAL错误(无效参数),但奇怪的是它在客户端尝试连接之后才失败.当客户端尝试连接时,它实际上已成功,但是当它尝试写入套接字时,ECONNreset失败(“通过对等方重置连接”).
另一个关键点是,您应该始终检查您的返回值.在处理套接字代码时,存在很多失败点,因此迂腐是值得的.如果系统调用失败,它将返回-1并将errno设置为适当的值.您可以使用strerror
function将错误代码转换为人类可读的消息,就像我在上面的示例中所做的那样.
以上是内存溢出为你收集整理的linux上的unix域套接字?全部内容,希望文章能够帮你解决linux上的unix域套接字?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)