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.
Aside from all other problems in your code, you are trying to read on the wrong file descriptor - it should be new_sd
, not sock
, which is a server socket and can only accept()
new connections.
Edit 0:
Big boo-boo:
if( new_sd = accept(sock, &name, (socklen_t*)&adrlen) < 0) { ...
This is equivalent to:
if( new_sd = (accept(sock, &name, (socklen_t*)&adrlen) < 0)) {
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
.
One thing that looks wrong in your code is that you're recv
ing on sock
when you should be recv
ing from new_fd
. Not sure why that would give EINVAL
though.
(EINVAL
errors are (usually) not detectable at compile time. File descriptors are plain int
s. The compiler cannot know which int
s are valid file descriptors at runtime, or if a particular combination of flags
is valid for the sockets you're using for instance.)
In the'recv()' call (in the server), the 'flags' parameter can't be 0:
recv(sock, buf, 14, 0)
Try something like:
recv(sock, buf, 14, MSG_WAITALL)
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.
精彩评论