在TCP客户端/服务器程序中未收到消息
问题描述:
我试图实现一个tcp客户端和tcp服务器。我能够建立连接,但是当我从客户端发送消息时,服务器没有收到它,是的,我查看了以前的帖子,并且发现了很多类似的问题。我确实按照他们,但我仍然得到同样的错误。我得到的错误是从服务器端:在TCP客户端/服务器程序中未收到消息
recv: Socket operation on non-socket
这是我的代码。如果你可以让我知道我做错了什么,我会很感激。我认为我的服务器实现存在问题。
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 3490
#define BACKLOG 10
int main()
{
struct sockaddr_in server;
struct sockaddr_in dest;
int status,socket_fd, client_fd,num;
socklen_t size;
char buffer[10240];
memset(buffer,0,sizeof(buffer));
int yes = 1;
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
fprintf(stderr, "Socket failure!!\n");
exit(1);
}
if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
memset(&server, 0, sizeof(server));
memset(&dest,0,sizeof(dest));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = INADDR_ANY;
if ((bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr)))== -1) { //sizeof(struct sockaddr)
fprintf(stderr, "Binding Failure\n");
exit(1);
}
if ((listen(socket_fd, BACKLOG))== -1){
fprintf(stderr, "Listening Failure\n");
exit(1);
}
while(1) {
size = sizeof(struct sockaddr_in);
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
//fprintf(stderr,"Accept Failure\n");
perror("accept");
exit(1);
}
printf("Server got connection from client %s\n", inet_ntoa(dest.sin_addr));
//buffer = "Hello World!! I am networking!!\n";
if ((num = recv(client_fd, buffer, 10239,0))== -1) {
//fprintf(stderr,"Error in receiving message!!\n");
perror("recv");
exit(1);
}
// num = recv(client_fd, buffer, sizeof(buffer),0);
buffer[num] = '\0';
printf("Message received: %s\n", buffer);
close(client_fd);
return 0;
//close(socket_fd);
}
}
客户:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define PORT 3490
int main(int argc, char *argv[])
{
struct sockaddr_in server_info;
struct hostent *he;
int socket_fd,num;
char *buffer;
if (argc != 2) {
fprintf(stderr, "Usage: client hostname\n");
exit(1);
}
if ((he = gethostbyname(argv[1]))==NULL) {
fprintf(stderr, "Cannot get host name\n");
exit(1);
}
if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) {
fprintf(stderr, "Socket Failure!!\n");
exit(1);
}
memset(&server_info, 0, sizeof(server_info));
server_info.sin_family = AF_INET;
server_info.sin_port = htons(PORT);
server_info.sin_addr = *((struct in_addr *)he->h_addr);
if (connect(socket_fd, (struct sockaddr *)&server_info, sizeof(struct sockaddr))<0) {
//fprintf(stderr, "Connection Failure\n");
perror("connect");
exit(1);
}
buffer = "Hello World!! I am networking!!\n";
if ((send(socket_fd,buffer, sizeof(buffer),0))== -1) {
fprintf(stderr, "Failure Sending Message\n");
close(socket_fd);
exit(1);
}
else {
printf("Message being sent: %s\n",buffer);
}
close(socket_fd);
}
答
你的第一个问题是放错地方的括号内。
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
实际上应该是
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {
正如你现在拥有它,client_fd
将被分配到的accept()
和-1
,因此返回值之间的相等测试的结果永远是零的情况下,的成功。
这是许多程序员避免在if语句中分配的原因之一。如果是这样写的
client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size);
if (client_fd == -1) {
然后错误不会发生。
答
我在gdb下运行了服务器,并在accept()调用后发现client_fd为0。这是一个无效的套接字fd,所以我看着那行代码,发现右括号是错误的:
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) {
应该是:
if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) {
否则,它的第一个,然后做比较将比较分配给client_fd,而您想要分配套接字,然后进行比较。
为了避免这种令人沮丧的错误,通常认为最好的做法是不要在'if'语句中放置任务。我会推荐:
client_fd = accept(...);
if (client_fd < 0) { ... }
而且,在客户端,send()调用使用“sizeof(buffer)”。 'buffer'是char *,指针的大小是4(在32位系统上),所以只会发送'Hell'。要发送完整的字符串,请使用“strlen(buffer)”来代替发送金额。
先生,非常感谢你!我得到了错误,但你写了与我一样的声明! :P但我明白我的错误! – ueg1990 2012-07-09 01:39:05
是的,刚刚发现并更新了答案。我复制并粘贴该行,并忘记编辑:) – 2012-07-09 01:39:43
但现在,我有另一个问题!我无法收到完整的讯息! :( 我想发送“Hello World !!我联网!!” – ueg1990 2012-07-09 01:40:16