【问题标题】:Sending data to and from using sockets in c在c中使用套接字发送数据
【发布时间】:2015-06-05 20:48:05
【问题描述】:

我正在为学校开发一个程序,但遇到了一些套接字问题。我从下面的程序中粘贴了写入和读取命令,因为我认为这些是问题所在。程序应获取明文文件并使用提供的密钥对其进行加密。

我的问题:当我使用“client [plaintext] [key] [port]”执行程序时,程序返回“Reading data from client -- 140 bytes”然后就挂起。我可以按 ctrl-c 并且程序打印 ptext 和 ktext 的正确输出,并且 37 个字节被发送回客户端(这是正确的字节数)。我觉得加密的文本也应该打印,但它没有。

两个问题:

1) 程序为什么会挂起?

2) 为什么看起来像是从服务器向客户端写入数据,但客户端却没有读取任何数据?

提前感谢您提供的任何帮助。

客户

n = write(sockfd,ptext,strlen(ptext));

bzero(crypt_text, BUF_MAX);
bzero(buffer, BUF_MAX);

while((n = read(sockfd,buffer,BUF_MAX))>0){
  printf("Reading data from Server -- %d bytes\n",n);
  strcat(crypt_text, buffer);
  bzero(buffer,BUF_MAX);
}
if (n < 0){
  error("ERROR reading from socket");
}

printf("%s", crypt_text);

服务器

while((n = read(newsockfd,buffer,512))>0){
  printf("Reading data from client -- %d bytes\n",n);
  strcat(full_text, buffer);
  bzero(buffer,BUF_MAX);
}
if (n < 0){
  error("ERROR reading from socket");
}

bzero (ptext,BUF_MAX);
bzero (ktext, BUF_MAX);
strcpy(ptext, strtok(full_text,"["));
strcpy(ktext, strtok(NULL, "["));

printf("ptext length ==%s %d\n\n",ptext,strlen(ptext)); //Prints the correct     plain text 
printf("ktext length ==%s %d\n\n",ktext,strlen(ktext)); //prints the correct key

crypt_text = encrypt(ptext, ktext);

n = write(newsockfd,crypt_text,strlen(crypt_text));
printf("WRITE TO CILENT ==== %d",n); //This returns the correct number of     bytes that should be sent back to client

if (n < 0){
  error("ERROR writing to socket");
}

【问题讨论】:

  • 你试过调试器吗? “为什么我的程序不起作用?”不鼓励在 SO 上提问。
  • 回答 2) 您的程序正在将数据从服务器读取到缓冲区中,而不是直接读取到您的程序中。有一些选项可以“刷新”缓冲区并关闭缓冲。然后你可能会看到你的输出。
  • read() 是阻塞 I/O 的一部分。 IIRC 你不能像那样使用read()。它总是会阻塞ie.keep等待客户端再次写东西

标签: c sockets


【解决方案1】:

按原样,您的客户端和服务器将始终挂起等待对方。这是因为read() 默认会阻塞,直到有新数据可用于从文件中获取(在本例中为套接字)。

仔细看代码:

  1. 客户端在进入读取循环之前向套接字写入一次
  2. 服务器只从套接字读取(好吧,再往下有一个write(),但它永远不会到达它)。循环第一次在服务器上运行时,它将读取客户端最初写入套接字的数据。
  3. 服务器处理它刚刚读取的数据并将其连接到full_text。然后它回到循环条件,再次调用read()read() 阻塞,因为此时没有其他内容可从套接字读取。
  4. 客户端进入一个类似的循环,尝试从套接字读取,并期待来自服务器的消息。
  5. 此时,服务器和客户端都被阻止等待来自对方的消息,这永远不会发生。

你换一种说法:你只写了一次套接字,不知何故你希望读多次。

您必须重新考虑您的设计。回到问题描述,通过一个简单的协议工作,在纸上试运行它,然后实现它——这就是它在现实世界中的完成方式:)

【讨论】:

    【解决方案2】:

    您的代码中还有其他错误。比如你这样写:

     strcat(full_text, buffer);
    

    但是buffer 不是 NUL 终止的。 n 字节已被读取,缓冲区的其余部分是不确定的。您应该在偏移量n 处设置一个'\0' 字节,并且只尝试读取BUF_MAX-1 字节以保持一个字节适用于所有情况并执行以下操作:

    buffer[n] = '\0';
    strcat(full_text, buffer);
    

    此外,您没有测试full_text 中是否有足够的空间供n+1 字节strcat 将在末尾复制。

    另一方面,当服务器接收到数据包时,可以将数据包切成不同大小的块。需要缓冲以确保可靠的客户端/服务器通信。要启用这种缓冲,您需要设计一个协议来确定何时完全接收到一个数据包:一个简单的协议是传输以'\n' 终止的行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 2015-10-03
      • 1970-01-01
      • 2017-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多