我最近使用Windows进行套接字编程,但我的任务要求学生使用Linux Socket标头(sys / socket.h)而不是Windows。 所以我从零开始,但程序冻结,即使它是一个非常简单的程序,除了只在连接时打印一条消息,它什么都不做。
Server.cpp
#include <sys/socket.h>
#include <cstdio>
#include <stdlib.h>
#include <cstring>
#include <errno.h>
#include <string>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 3490
#define BACKLOG 10
int main(void){
int sockfd, new_fd;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
socklen_t sin_size;
if((sockfd = socket(PF_INET, SOCK_STREAM, 0))==-1){
perror("Socket creation failed");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr))==-1){
perror("Socket binding failed");
exit(1);
}
if(listen(sockfd, BACKLOG) == -1){
perror("Socket listening failed");
exit(1);
}
sin_size = (socklen_t)sizeof(struct sockaddr_in);
while(true){
printf("Loop Test"); // This is not displayed at all
if((new_fd = accept(sockfd, (struct sockaddr*)&their_addr, &sin_size))==-1){
perror("Connetion accepting failed");
exit(1);
}
printf("Server got connection from %s\n", inet_ntoa(their_addr.sin_addr));
}
return 0;
}
Client.cpp
#include <sys/socket.h>
#include <cstdio>
#include <stdlib.h>
#include <cstring>
#include <errno.h>
#include <string>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 3490
int main(void){
int sockfd;
struct sockaddr_in their_addr;
if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){
perror("Socket generating failed");
exit(1);
}
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(PORT);
their_addr.sin_addr.s_addr = INADDR_LOOPBACK;
if(connect(sockfd, (struct sockaddr*)&their_addr, sizeof(struct sockaddr)) == -1){
perror("Connection failed");
exit(1);
}
printf("Loop test"); // This is not displayed no matter if server is on or not
return 0;
}
正如我在代码中提到的,它只是停止,并且不显示perror和printf(用于调试)。 为什么会这样? (我正在使用Ubuntu)
答案 0 :(得分:1)
您的计划有两个问题。第一个是相对较小的,即您不会使用printf
结束"\n"
语句。因为输出是缓冲的,你不会立即看到它。
然而,如果你不会有一个简单而又烦人的错误,那么单独就不可见了(尽管它确实会让调试变得更难,因为你不确定发生了什么) - 你无法将INADDR_LOOPBACK转换为带有{{1的大端}}。具有讽刺意味的是,你为htonl
做了这个(虽然好的风格没有做任何真实的事情,因为0总是0),但不要在真正重要的地方做。