Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的Basic套接字编程_C_Sockets_If Statement - Fatal编程技术网

C语言中的Basic套接字编程

C语言中的Basic套接字编程,c,sockets,if-statement,C,Sockets,If Statement,所以我在我的程序中遇到了一个奇怪的问题,这基本上是C语言中的一个客户机/服务器套接字编程示例。我花了很多时间来解决这个问题,但我似乎无法找到导致问题的原因 如果需要的话,我可以发布更多的细节,但以下是不可行的 while(1) { char word[256]; gets(word); printf("%s",word); if(strcmp(word, "TRANSLATE") == 0 || strcmp(word, "GET") == 0 ||strcmp(wor

所以我在我的程序中遇到了一个奇怪的问题,这基本上是C语言中的一个客户机/服务器套接字编程示例。我花了很多时间来解决这个问题,但我似乎无法找到导致问题的原因

如果需要的话,我可以发布更多的细节,但以下是不可行的

       while(1)
{
char word[256];
gets(word);
printf("%s",word);

     if(strcmp(word, "TRANSLATE") == 0 || strcmp(word, "GET") == 0 ||strcmp(word, "STORE") == 0 || strcmp(word, "EXIT") == 0)
{
    if(strcmp(word, "TRANSLATE") == 0)
    {
        if(send(sock , word , strlen(word) , 0)<0)
        {
            printf("Send Error\n");
            return 1;
        }
        bzero(server_reply,2000);
        if(recv(sock , server_reply , 2000 , 0)<0)
        {
            puts("Recieving Error\n");
        }
        //Print out 200ok message
        printf("%s\n", server_reply);
        //Get the first word
        gets(word2);
        while(strcmp(word2,"." )!= 0)
        {

            if(send(sock , word2 , strlen(word2) , 0)<0)
            {
                printf("Send Error\n");
                return 1;
            }
            gets(word2);    
        }
        if(recv(sock , server_reply , 2000 , 0)<0)
        {
            puts("Recieving Error\n");
        }
            printf("%s\n", server_reply);
        //STILL NEED TO WORK ON PARSING OUT SPACES BECAUSE RESULT IS IN A STRING, JUST WITH SPACES.
        //ALSO NEED TO DO SERVER SIDE CAPITALIZATION
    }
    if(strcmp(word, "GET") == 0)
    {

        printf("Getting");
    /*
        if(send(sock , word , strlen(word) , 0)<0)
        {
            printf("Send Error\n");
            return 1;
        }
        bzero(server_reply,2000);
        if(recv(sock , server_reply , 2000 , 0)<0)
        {
            puts("Recieving Error\n");
        }
        //Print out 200ok message
        printf("%s\n", server_reply);
        /*
         if(recv(sock , server_reply , 2000 , 0)<0)
        {
            puts("Recieving Error\n");
        }
        //Print out the KANSAS message
        printf("%s\n", server_reply);
        */
    }
}
while(1)
{
字符字[256];
获取(单词);
printf(“%s”,单词);
如果(strcmp(单词,“TRANSLATE”)=0 | | strcmp(单词,“GET”)=0 | | strcmp(单词,“STORE”)=0 | | strcmp(单词,“EXIT”)=0
{
如果(strcmp(字,“翻译”)==0)
{

如果(send(sock,word,strlen(word),0)您应该在每个
printf
格式控制字符串和/或调用的末尾添加
\n

程序中的主要问题是错误地认为一个给定的
send
(或
write
)对应于另一侧的一个
recv
(或
read

一个实现只是一个字节流;没有隐含的消息边界。因此,应用程序应该缓冲并显式地将该流拆分为有意义的消息

它可能发生,而且确实发生,一方能够同时
发送
写入
4000字节,然后再发送1000字节,但另一方将首先
接收
(或
读取
),例如39字节,然后1字节,然后1960字节,然后3000字节。这样你就理解了“消息”没有完整的,只有一个字节流

另一个困难是这种行为是不可复制的。下次运行服务器和客户端程序时,它们的行为将不同

在实践中,很好地定义消息边界的位置是很有帮助的。您可以这样做,即在每条消息的开头添加一些内容长度(在HTTP中,回复头中的
content-length:
属性)。您还可以确定消息是一条单行,并有一条换行终止它(然后,你可能需要一个惯例来避开内部换行符),比如看。当然,你应该在两边都缓冲

您可能希望使用多路复用调用测试套接字(或管道)的可读写性,如

我强烈建议你读点书,读点书

顺便说一句,始终测试系统调用是否失败。请参阅并使用或(通常与)

当然,使用所有警告和调试信息(
gcc-Wall-g
)进行编译,并使用调试器(
gdb
)(也可能)。您可能希望在不同的终端上使用两个
gdb
会话(一个用于服务器,一个用于客户端)进行调试


顺便说一句,不要使用过时的弃用函数,而是使用标准。

您应该在每个
printf
格式控制字符串和/或调用的末尾添加
\n

程序中的主要问题是错误地认为一个给定的
send
(或
write
)对应于另一侧的一个
recv
(或
read

一个实现只是一个字节流;没有隐含的消息边界。因此,应用程序应该缓冲并显式地将该流拆分为有意义的消息

它可能发生,而且确实发生,一方能够同时
发送
写入
4000字节,然后再发送1000字节,但另一方将首先
接收
(或
读取
),例如39字节,然后1字节,然后1960字节,然后3000字节。这样你就理解了“消息”没有完整的,只有一个字节流

另一个困难是这种行为是不可复制的。下次运行服务器和客户端程序时,它们的行为将不同

在实践中,很好地定义消息边界的位置是很有帮助的。您可以这样做,即在每条消息的开头添加一些内容长度(在HTTP中,回复头中的
content-length:
属性)。您还可以确定消息是一条单行,并有一条换行终止它(然后,你可能需要一个惯例来避开内部换行符),比如看。当然,你应该在两边都缓冲

您可能希望使用多路复用调用测试套接字(或管道)的可读写性,如

我强烈建议你读点书,读点书

顺便说一句,始终测试系统调用是否失败。请参阅并使用或(通常与)

当然,使用所有警告和调试信息(
gcc-Wall-g
)进行编译,并使用调试器(
gdb
)(也可能)。您可能希望在不同的终端上使用两个
gdb
会话(一个用于服务器,一个用于客户端)进行调试


顺便说一句,不要使用过时的弃用函数,而是使用标准。

您应该在每个
printf
格式控制字符串和/或调用的末尾添加
\n

程序中的主要问题是错误地认为一个给定的
send
(或
write
)对应于另一侧的一个
recv
(或
read

一个实现只是一个字节流;没有隐含的消息边界。因此,应用程序应该缓冲并显式地将该流拆分为有意义的消息

它可能发生,而且确实发生,一方能够同时
发送
写入
4000字节,然后再发送1000字节,但另一方将首先
接收
(或
读取
),例如39字节,然后1字节,然后1960字节,然后3000字节。这样你就理解了“消息”没有完整的,只有一个字节流

另一个困难是这种行为是不可复制的。下次运行服务器和客户端程序时,它们的行为将不同

实际上,这是一种帮助
  #include<stdio.h>
  #include<string.h>  //strlen
#include<sys/socket.h>
#include<arpa/inet.h>   //inet_addr
#include<unistd.h>  //write

int main(int argc , char *argv[])
{
   int socket_desc , client_sock , c , read_size;
   struct sockaddr_in server , client;
   char client_message[2000];

   //Create socket
   socket_desc = socket(AF_INET , SOCK_STREAM , 0);
   if (socket_desc == -1)
   {
       printf("Could not create socket");
   }
   puts("Socket created");

   //Prepare the sockaddr_in structure
   server.sin_family = AF_INET;
   server.sin_addr.s_addr = INADDR_ANY;
   server.sin_port = htons( 5149 );

   //Bind
   if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
   {
       //print the error message
       printf("bind failed. Error");
       return 1;
   }
   puts("bind done");

   //Listen
   listen(socket_desc , 3);

   //Accept and incoming connection
   puts("Waiting for incoming connections...");
   c = sizeof(struct sockaddr_in);

   //accept connection from an incoming client
   client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
   if (client_sock < 0)
   {
       printf("accept failed");
       return 1;
   }
   puts("Connection accepted");

   //Receive a message from client
   while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
   {
    if(strcmp(client_message,"TRANSLATE")==0)
    {
        *(client_message + read_size) = '\0';
        char word[256]="200 OK TRANSLATE";
        write(client_sock, word, strlen(word));
        /*
         while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
         {
            *(client_message + read_size) = '\0';
            puts(client_message);
            write(client_sock,client_message,strlen(client_message));
            if(strcmp(client_message,".")==0)
            {
                printf("breaking");
                break;
            }
            printf("IN while loop");
         }

        printf("Out of while loop");
        */
    }
    if(strcmp(client_message,"GET")==0)
    {
        *(client_message + read_size) = '\0';
        char word[256]="200 OK GET";
        write(client_sock, word , strlen(word));
        char word2[256]="I don't think we're in Kansas anymore.";
        write(client_sock, word2 , strlen(word2));
    }
    if(strcmp(client_message,"STORE")==0)
    {
        char word[256]="200 OK STORE";
        write(client_sock, word , strlen(word));
    }
   }

   if(read_size == 0)
   {
       puts("Client disconnected");
       fflush(stdout);
   }
   else if(read_size == -1)
   {
       printf("recv failed");
   }

   return 0;
}