BSD 套接字 - 使用发送和接收
我正在尝试使用 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 错误消息仅表示“无效参数”。但我不知道如何准确地解释它......如果一个参数无效,为什么它甚至会编译?
如果有人能指出我在这里做错了什么,我将非常感激。您想指出的任何其他小注释都将受到欢迎。感谢您的任何帮助。
I am trying to implement a simple chat program in linux using bsd sockets. Right now I am just trying to send and receive one message to the server from a client. Whenever I run the code, recv returns -1 and the errno code is 22.
Server code -
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;
}
Client code -
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;
}
Even though I get the error on the server side, I do not get the error message on the client side - it just exits normally.
According to - http://www.workers.com.br/manuais/53/html/tcp53/mu/mu-7.htm the errno 22 error message just means "Invalid argument". But I don't know how exactly to interpret that...if an argument was invalid why would it even compile?
If anyone can point out what I'm doing wrong here I would be very grateful. And any other small notes you feel like pointing out would be welcomed. Thanks for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
除了代码中的所有其他问题之外,您还尝试读取错误的文件描述符 - 它应该是
new_sd
,而不是sock
,它是一个服务器套接字并且只能accept()
新连接。编辑 0:
大嘘声:
这相当于:
所以
new_sd
得到完全错误的值。一般智慧是不要将作业放入条件中。考虑使用高警告级别进行编译,至少是-Wall -pedantic
。Aside from all other problems in your code, you are trying to read on the wrong file descriptor - it should be
new_sd
, notsock
, which is a server socket and can onlyaccept()
new connections.Edit 0:
Big boo-boo:
This is equivalent to:
So
new_sd
gets totally wrong value. General wisdom is not to put assignments into conditionals. Consider compiling with high warning levels, at least-Wall -pedantic
.代码中看起来错误的一件事是,当您应该从
new_fd< 中
recv
时,却在sock
上recv
了。 /代码>。但不确定为什么会给出EINVAL
。(
EINVAL
错误(通常)在编译时无法检测到。文件描述符是普通的int
。编译器无法知道哪些int
是有效的运行时的文件描述符,或者特定的标志
组合对于您正在使用的套接字是否有效。)One thing that looks wrong in your code is that you're
recv
ing onsock
when you should berecv
ing fromnew_fd
. Not sure why that would giveEINVAL
though.(
EINVAL
errors are (usually) not detectable at compile time. File descriptors are plainint
s. The compiler cannot know whichint
s are valid file descriptors at runtime, or if a particular combination offlags
is valid for the sockets you're using for instance.)在“recv()”调用(在服务器中)中,“flags”参数不能为 0:
尝试如下操作:
请参阅“man”页面以获取“flags”参数的完整选项列表。人们必须明智地决定如何接收这一信息。
客户端没有收到错误消息(INVALID ARG)的原因是因为它没有执行任何接收操作...只有服务器正在执行接收操作。
In the'recv()' call (in the server), the 'flags' parameter can't be 0:
Try something like:
See the 'man' page for the whole list of options for 'flags' parameter. One must be judicious here on how the message is to be received.
The reason why the client doesn't get the error message (INVALID ARG) is because it doesn't do any recv's ... only the server is doing receive's.