我正在尝试使用bsd套接字在linux中实现一个简单的聊天程序。现在我只是尝试从客户端向服务器发送和接收一条消息。每当我运行代码时,recv返回-1并且errno代码为22.
服务器代码 -
struct sockaddr name;
char buf[80];
int main(int agrc, char** argv) {
int sock, new_sd; //sock is this socket, new_sd is connection socket
int adrlen, cnt;
name.sa_family = AF_UNIX;
strcpy(name.sa_data, "/tmp/servsock");
adrlen = strlen(name.sa_data) + sizeof(name.sa_family);
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
cout<<"\nserver socket failure "<<errno;
cout<<"\nServer: ";
exit(1);
}
unlink("/tmp/servsock");
if(bind (sock, &name, adrlen) < 0)
cout<<"\nBind failure "<<errno;
if(listen(sock, 5) < 0)
cout<<"\nlisten error "<<errno;
while(1) {
if( new_sd = accept(sock, &name, (socklen_t*)&adrlen) < 0) {
cout<<"\nserver accept failure "<<errno;
exit(1);
}
char* buf = new char[14];
if(recv(sock, buf, 14, 0) < 0) {
cout<<"\nError receiving data "<<errno;
exit(1);
}
} //end while
return 0;
}
客户代码 -
struct sockaddr name;
int main(int agrc, char** argv) {
int sock, new_sd, adrlen, cnt;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
cout<<"\nserver socket failure "<<errno;
cout<<"\nServer: ";
exit(1);
}
//stuff for server socket
name.sa_family = AF_UNIX;
strcpy(name.sa_data, "/tmp/servsock");
adrlen = strlen(name.sa_data) + sizeof(name.sa_family);
if(connect(sock, &name, adrlen) < 0) {
cout<<"\nclient connection failure "<<errno;
exit(1);
}
cout<<"\nSuccessful connection from client 1";
std::string buf = "\nClient 1 Here";
if(send(sock, buf.c_str(), strlen(buf.c_str()), 0) < 0) {
cout<<"\nError sending data from client 1 "<<errno;
exit(1);
}
cout<<"\nExiting normally";
return 0;
}
即使我在服务器端收到错误,我也没有在客户端收到错误消息 - 它只是正常退出。
根据 - http://www.workers.com.br/manuais/53/html/tcp53/mu/mu-7.htm,errno 22错误消息仅表示“无效参数”。但我不知道究竟如何解释......如果一个论证无效,为什么它甚至会编译?
如果有人能指出我在这里做错了什么,我将非常感激。你想要指出的任何其他小笔记都会受到欢迎。谢谢你的帮助。
答案 0 :(得分:5)
除了代码中的所有其他问题之外,您正在尝试读取错误的文件描述符 - 它应该是new_sd
,而不是sock
,这是服务器套接字并且只能accept()
个新连接。
大嘘声:
if( new_sd = accept(sock, &name, (socklen_t*)&adrlen) < 0) { ...
这相当于:
if( new_sd = (accept(sock, &name, (socklen_t*)&adrlen) < 0)) {
所以new_sd
的价值完全错误。一般的智慧不是将任务纳入条件。考虑使用高警告级别进行编译,至少-Wall -pedantic
。
答案 1 :(得分:2)
在您的代码中出现问题的一件事是,当recv
sock
recv
时,您new_fd
EINVAL
。不知道为什么会给EINVAL
。
(int
错误(通常)在编译时无法检测到。文件描述符是普通的int
s。编译器无法知道哪些flags
是运行时的有效文件描述符,或者如果{{1}}的特定组合对您正在使用的套接字有效。)
答案 2 :(得分:0)
在'recv()'调用中(在服务器中),'flags'参数不能为0:
recv(sock, buf, 14, 0)
尝试类似:
recv(sock, buf, 14, MSG_WAITALL)
有关'flags'参数的完整选项列表,请参阅'man'页面。在这里必须明智地了解如何接收消息。
客户端没有收到错误消息(INVALID ARG)的原因是因为它没有执行任何recv ...只有服务器正在接收错误消息。