C posix插座,can';t将数据从客户端发送到服务器

C posix插座,can';t将数据从客户端发送到服务器,c,sockets,posix,C,Sockets,Posix,我想创建一个客户端并将其连接到服务器。我知道客户端进程在服务器之前开始运行,所以我在无限循环中进行连接,直到它被接受为止。然后我想将消息输入到客户端并发送到服务器,服务器将在屏幕上打印它们。我从代码中删除了所有错误检测,以缩短代码,我知道它们必须存在。我试着这样做,但服务器什么也没收到,客户端无法进行第二次连接 服务器 客户端 intmain(intargc,char*argv[]) { int-sockfd; 服务地址中的结构sockaddr\u; 字符缓冲区[256]; sockfd=套接字

我想创建一个客户端并将其连接到服务器。我知道客户端进程在服务器之前开始运行,所以我在无限循环中进行连接,直到它被接受为止。然后我想将消息输入到客户端并发送到服务器,服务器将在屏幕上打印它们。我从代码中删除了所有错误检测,以缩短代码,我知道它们必须存在。我试着这样做,但服务器什么也没收到,客户端无法进行第二次连接

服务器

客户端

intmain(intargc,char*argv[])
{
int-sockfd;
服务地址中的结构sockaddr\u;
字符缓冲区[256];
sockfd=套接字(AF_INET,SOCK_STREAM,0);
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=inet_addr(“127.0.0.1”);
serv_addr.sin_port=htons(5000);
而(1){
而((connect(sockfd,(struct sockaddr*)和serv_addr,sizeof(serv_addr))<0)){
printf(“正在尝试连接”);
睡眠(1);
}
printf(“已连接\n请输入消息”);
scanf(“%s”,缓冲区);
写入(sockfd、缓冲区、strlen(缓冲区));
}
关闭(sockfd);
返回0;
}

我不知道您是如何编译代码的,但是如果您在gcc中设置了警告标志(
-Wall
),您就会收到此警告

server.c: In function ‘main’:
server.c:33:44: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
 if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) {
根据它,我改变了,这个

if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) {
到。。(注意额外的括号)

我没有收到更多的警告,服务器捕捉到了客户端的消息

这是我调试时运行的服务器(这基本上是您的代码,稍作改动)

int sockfd,newsockfd;
socklen_t clilen;
字符缓冲区[256];
int n字节=0;
服务地址中的结构sockaddr\u,cli\u addr;
sockfd=套接字(AF_INET,SOCK_STREAM,0);
serv_addr.sin_family=AF_INET;
//serv_addr.sin_addr.s_addr=inet_addr(“127.0.0.1”);
serv_addr.sin_addr.s_addr=INADDR_ANY;
serv_addr.sin_port=htons(5007);
绑定(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
如果(监听(sockfd,5)=0{

虽然((nbytes=read(newsockfd,buffer,sizeof(buffer)))我不知道您是如何编译代码的,但是如果您在gcc中设置了警告标志(
-Wall
),您就会收到此警告

server.c: In function ‘main’:
server.c:33:44: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
 if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) {
根据它,我改变了,这个

if (newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr,&clilen) >= 0) {
至..(注意额外的括号)

我没有收到更多的警告,服务器捕捉到了客户端的消息

这是我调试时运行的服务器(这基本上是您的代码,稍作改动)

int sockfd,newsockfd;
socklen_t clilen;
字符缓冲区[256];
int n字节=0;
服务地址中的结构sockaddr\u,cli\u addr;
sockfd=套接字(AF_INET,SOCK_STREAM,0);
serv_addr.sin_family=AF_INET;
//serv_addr.sin_addr.s_addr=inet_addr(“127.0.0.1”);
serv_addr.sin_addr.s_addr=INADDR_ANY;
serv_addr.sin_port=htons(5007);
绑定(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
如果(监听(sockfd,5)=0{

虽然((nbytes=read(newsockfd,buffer,sizeof(buffer)))另一个问题是每次在客户端连接时都必须创建套接字,如:

while (1) {
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    while ((connect(sockfd,(struct sockaddr *)  &serv_addr,sizeof(serv_addr)) < 0)) {
       printf("trying to connect\n");
       sleep(1);
    }
    printf("connected\nplease, enter a message\n");
    scanf("%s", buffer);
     write(sockfd, buffer, strlen(buffer));
}
while(1){
sockfd=套接字(AF_INET,SOCK_STREAM,0);
而((connect(sockfd,(struct sockaddr*)和serv_addr,sizeof(serv_addr))<0)){
printf(“正在尝试连接”);
睡眠(1);
}
printf(“已连接\n请输入消息”);
scanf(“%s”,缓冲区);
写入(sockfd、缓冲区、strlen(缓冲区));
}

另一个问题是,我们每次在客户端连接时都必须创建套接字,如:

while (1) {
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    while ((connect(sockfd,(struct sockaddr *)  &serv_addr,sizeof(serv_addr)) < 0)) {
       printf("trying to connect\n");
       sleep(1);
    }
    printf("connected\nplease, enter a message\n");
    scanf("%s", buffer);
     write(sockfd, buffer, strlen(buffer));
}
while(1){
sockfd=套接字(AF_INET,SOCK_STREAM,0);
而((connect(sockfd,(struct sockaddr*)和serv_addr,sizeof(serv_addr))<0)){
printf(“正在尝试连接”);
睡眠(1);
}
printf(“已连接\n请输入消息”);
scanf(“%s”,缓冲区);
写入(sockfd、缓冲区、strlen(缓冲区));
}

一旦
connect()
失败,就不能保证可以在同一个套接字上再次调用它。通常最好在每次
connect()
尝试时销毁并重新创建套接字。但是,无论哪种方式,一旦
connect()
成功,您的客户端都不会在调用
connect()之前关闭连接的套接字
在下一个循环迭代中再次出现。如果您从代码中删除了所有错误处理,您怎么可能期望能够调试它?这不是一个合理的策略。在您提供错误代码之前,这也不是一个可以回答的问题,在您将错误处理放回之前,您无法做到这一点;并且您无法证明您没有错误代码直到同上。一旦
connect()
失败,就不能保证可以在同一个套接字上再次调用它。通常最好在每次
connect()
尝试时销毁并重新创建套接字。但是,无论如何,只要
connect()
成功,您的客户端在调用
connect()之前没有关闭连接的套接字
在下一个循环迭代中再次出现。如果您从代码中删除了所有错误处理,您怎么可能期望能够调试它?这不是一个合理的策略。在您提供错误代码之前,这也不是一个可以回答的问题,在您将错误处理放回之前,您无法做到这一点;并且您无法证明您没有错误代码直到同上。您应该只有一个套接字并重用它(除非您希望同时连接到多个服务器点)您也没有从while循环中正确断开,因此您将永远没有机会正确关闭套接字。这将影响您的测试,因为您必须等待操作系统在退出后释放该端口。您应该只有一个套接字并重新使用它(除非您想同时连接到多个服务器点)您也没有从while循环中正确断开,因此您将永远没有机会正确关闭套接字。这将损害您的测试,因为您将不得不等待操作系统释放该套接字
while (1) {
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    while ((connect(sockfd,(struct sockaddr *)  &serv_addr,sizeof(serv_addr)) < 0)) {
       printf("trying to connect\n");
       sleep(1);
    }
    printf("connected\nplease, enter a message\n");
    scanf("%s", buffer);
     write(sockfd, buffer, strlen(buffer));
}