【发布时间】:2014-10-04 06:52:04
【问题描述】:
信息
[root@xilinx Downloads]# uname -a
Linux xilinx 2.6.32-71.el6.x86_64 #1 SMP Wed Sep 1 01:33:01 EDT 2010 x86_64 x86_64 x86_64 GNU/Linux
我正在尝试使用 Unix 套接字制作一个简单的聊天应用程序:
编译代码后,我首先在一个终端上运行 server,它说,等待连接。然后我在同一台计算机上的另一个终端上启动 client,它连接成功。然后客户端发送第一条消息。服务器收到它非常好。
但是在那之后发生了一些奇怪的事情。我必须输入几次才能使其正常工作并获得整个消息。
这是一个简单的运行输出:
服务器端
[root@xilinx Downloads]# ./server
Waiting for a connection...
Connected.
客户端
[root@xilinx Downloads]#
[root@xilinx Downloads]#
[root@xilinx Downloads]# ./client
Trying to connect...
Connected.
SingleWord //客户端将此消息发送到服务器
服务器端
>received<SingleWord //server receives this- good.
IamServer // Now server sends some message
客户端 ///我必须按几次回车才能得到整个消息
echo> Ia>
echo> mS>
echo> er>
echo> ve>
echo> r
请帮我解决这个问题:
代码如下。
Server.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "echo_socket"
int main(void) {
int s, s2, t, len;
struct sockaddr_un local, remote;
char str[100];
char str2[100];
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
local.sun_family = AF_UNIX;
strcpy(local.sun_path, SOCK_PATH);
unlink(local.sun_path);
len = strlen(local.sun_path) + sizeof(local.sun_family);
if (bind(s, (struct sockaddr * ) & local, len) == -1) {
perror("bind");
exit(1);
}
if (listen(s, 5) == -1) {
perror("listen");
exit(1);
}
for (;;) {
int done, n;
printf("Waiting for a connection...\n");
t = sizeof(remote);
if ((s2 = accept(s, (struct sockaddr * ) & remote, & t)) == -1) {
perror("accept");
exit(1);
}
printf("Connected.\n");
done = 0;
do {
while (1) {
n = recv(s2, str, 100, 0);
printf(">received<%s", str);
if (n <= 0) {
if (n < 0) perror("recv");
printf("error");
done = 1;
}
//m = fgets(str2,100,stdin);
if (!done)
while (fgets(str2, 100, stdin) > 0) {
if (send(s2, str2, strlen(str2), 0) < 0) {
perror("send");
//if (send(s2, str2, m, 0) < 0) {
//perror("send");
done = 1;
}
}
}
} while (!done);
close(s2);
}
return (0);
}
Client.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define SOCK_PATH "echo_socket"
int main(void) {
int s, t, len;
struct sockaddr_un remote;
char str[100];
char str2[100];
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(1);
}
printf("Trying to connect...\n");
remote.sun_family = AF_UNIX;
strcpy(remote.sun_path, SOCK_PATH);
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
if (connect(s, (struct sockaddr * ) & remote, len) == -1) {
perror("connect");
exit(1);
}
printf("Connected.\n");
while (1) {
while (printf("> "), fgets(str, 100, stdin), !feof(stdin)) {
if (send(s, str, strlen(str), 0) < 0) {
perror("send");
exit(1);
}
if ((t = recv(s, str2, strlen(str2), 0)) > 0) {
str2[t] = '\0';
printf("echo> %s", str2);
} else {
if (t < 0) perror("recv");
else printf("Server closed connection\n");
exit(1);
}
}
}
close(s);
return 0;
}
【问题讨论】:
-
缩进会很好,不是每个人都足够聪明和流利地使用 C 套接字编程来编写或读取没有缩进的代码。
-
没有深入研究,我假设问题与阻塞 IO 有关,因为您没有任何努力切换到非阻塞。
-
这一行: if ((t = recv(s, str2, strlen(str2), 0)) > 0) { 试图获取数组 str2 中字符串的长度,但是,有在 recv() 完成执行之前,没有任何东西放入该数组中。