【问题标题】:socket programming in c unixc unix 中的套接字编程
【发布时间】:2015-05-30 09:42:07
【问题描述】:

我编写了一个基于服务器/客户端的 c 程序。该程序的基本功能是客户端将发送一个字符,例如服务器,服务器将增加它并将字符发送回。因此,如果客户端发送“a”,它将收到“b”。但是当客户端发送一个“q”时,服务器应该关闭连接。该程序正在做它应该做的事情,但在客户端它打印“输入一个字符”和“来自服务器的字符”两次。发送“q”也会关闭连接,但前提是您第二次发送。

这是服务器端代码

void *client_thread(void *client_sockfd){
    int socket=*(int *)client_sockfd;
    while(1){
        read(socket, &ch, 1);
        if(ch=='q')
        {
            close(socket); 
        }
        else 
        {
            ch++;
            write(socket, &ch, 1);
        }
    }
    //close(socket);
    printf("Connection closed with %d",socket);       

}//end fucntion

客户端代码

while(1)
{
    printf("Enter a character");
    scanf("%c",&ch);  
    write(sockfd, &ch, 1);
    read(sockfd, &ch, 1);
    printf("char from server = %c\n", ch);

    //  close(sockfd);
    //exit(0);
}
if(ch=='q'){
    printf("Server closed the connection");
}

【问题讨论】:

  • 您可能需要添加一些代码来检查读取和写入是否实际成功

标签: c sockets unix


【解决方案1】:

scanf 一次读取一个字符,所以当你输入一个字符并回车时,第一个循环会读取字符,第二个循环会读取换行符。

你可以使用

scanf("%c%*c", &ch);

读取两个字符,但只存储第一个字符。

【讨论】:

  • 这适用于不打印两次但现在它关闭随机字符的连接。
  • 使用这个while((n = read(sockfd, &ch, 1))>0) 而不是while(1) @AliRehman
  • 我必须在哪里使用它?
【解决方案2】:

客户端: 这里打印了两行,因为有两个输入,一个是你的角色,第二个是 enter\n

所以在客户端使用scanf("%c%c",&ch);

服务器端: 第二次使用while((n = read(sockfd, &ch, 1))>0) 阻止它自动终止连接。 read 语句返回读取的字节数。

因为您提供的值在增加后不会被删除。原因是:

  • 假设您的输入是a,那么服务器会向您响应b,并且由于您没有在服务器端检查readreturn 值,因此它每次都会递增ch它到达q 并且套接字被关闭。
  • 当服务器增加值时,它也会将其发送给客户端,但由于客户端处于scanf 模式,直到read 语句才能获得输入,因此您看不到自动增量价值。而且增量非常快,以至于在您下一次输入之前,套接字已经终止。

【讨论】:

  • 非常感谢。它现在工作正常。我还在客户端 while(m>0) 中编辑了 while 循环,其中 m 具有客户端读取的返回值。它没有做任何不寻常的事情,但请告诉我这样做是否可以。 @Subinoy
  • 始终使用函数的返回值。对节目有好处。 :-)
  • 客户端的 while 将等到服务器响应,直到那时你不能提供输入 @AliRehman
  • 我觉得你是新人,请看这个stackoverflow.com/help/someone-answers@AliRehman
【解决方案3】:
printf("Enter a character");
scanf("%c",&ch); 

您实际上在此处输入了两个字符,一个对应于您按下的每个键,第二个来自 Enter,即换行符/n。这就是为什么

的所有其他输出
printf("char from server = %c\n", ch);

大概是:

char from server =

然后有一个空行,然后是另一个输出。如果您这样做:

printf("char from server = %d\n", (int)ch);
                       //   ^ not %c

int 的演员表在那儿并不是真正必要的,但强调了这个想法;您现在将获得字符的小数 ASCII 值,并且现在每隔一行将是:

char from server = 10

这是换行符。想要解决这个已经赶上了无数 C 新手的问题的方法,see my answer here

【讨论】:

    【解决方案4】:

    您的程序正在执行以下操作...

    1. 打印消息“输入一个字符”并阻止等待 STDIN
    2. 用户键入 'a' 和 '\n' - scanf() 在换行之前不会返回控制
    3. 写入“a”,读取“b”,打印“b”,然后提示“输入字符”
    4. Scanf 已经有一个字符 (\n) 所以它会立即返回
    5. 写入 '\n',读取 '\n'+1,打印 '\n'+1 并提示“输入字符”
    6. 从 1 开始重复。

    这就是为什么您会看到两次“输入字符”。

    至于必须发送'q'两次,您的服务器循环在收到'q'时不会退出,它会调用close并继续读取。之后的每次读取都将失败并立即返回错误代码。同样,您的客户端循环也不会中断。

    捕获并测试您的返回值。此外,使用调试器逐步完成 - 这将回答您关于 C 的许多问题,而无需等待论坛回复。

    【讨论】:

      猜你喜欢
      • 2014-06-02
      • 2015-07-20
      • 2015-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      相关资源
      最近更新 更多