我正在尝试实现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);
}
答案 0 :(得分: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)”代替要发送的金额。
答案 1 :(得分:0)
你的第一个问题是错误的括号。
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) {
然后就不会发生错误。