0

有人可以帮助确定为什么我的服务器不能接受来自客户端的多条消息吗?

我试图让流程如下所示:
1. 客户端向服务器发送消息大小
2. 服务器接收大小并发送回响应。在这种情况下为 0。
3. 客户端检查响应,然后将消息写入服务器。
4. 服务器读取消息并打印出来。

我遇到的问题是第 4 步的 accept() 永远不会解除阻塞。

客户

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(int argc, char *argv[])
{
int sock = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in s_address;
s_address.sin_family = AF_INET;
s_address.sin_port = htons(51717);
s_address.sin_addr.s_addr = INADDR_ANY;
if (connect(sock, (struct sockaddr *) &s_address, sizeof(s_address)) < 0) {
    printf("ERROR: Cannot connect()\n");
    exit(0);
}

char *org_msg = "Hello";

printf("Writing size of Hello\n");
char msg1[1];
msg1[0] = sizeof(org_msg);
write(sock, msg1, sizeof(msg1));

printf("Waiting for response from server\n");
struct sockaddr_in c_address;
socklen_t c_length = sizeof(c_address);
int new_sock = accept(sock, (struct sockaddr *) &c_address, &c_length);

printf("Reading response from server\n");
char stat[1];
read(new_sock, stat, 1);

if (atoi(stat) == 0) {
    printf("Writing Hello to server\n");
    write(sock, org_msg, sizeof(org_msg));
}
close(sock);
close(new_sock);
}

服务器

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(int argc, char *argv[])
{
int sock = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in s_address;
s_address.sin_family = AF_INET;
s_address.sin_port = htons(51717);
s_address.sin_addr.s_addr = INADDR_ANY;
if (bind(sock, (struct sockaddr *) &s_address, sizeof(s_address)) < 0) {
    printf("ERROR: Cannot bind()\n");
    exit(0);
}

listen(sock, 3);

printf("Waiting for client message\n");
struct sockaddr_in c_address;
socklen_t c_length = sizeof(c_address);
int new_sock = accept(sock, (struct sockaddr *) &c_address, &c_length);

printf("Reading client message\n");
char msg[1];
read(new_sock, msg, 1);

printf("Writing response to client\n");
char stat[1];
stat[0] = '0';
write(new_sock, stat, sizeof(stat));

printf("Waiting for client message\n");
int new_sock2 = accept(sock, (struct sockaddr *) &c_address, &c_length);

printf("Reading client message\n");
char msg2[atoi(msg)];
read(new_sock2, msg2, sizeof(msg2));

printf("MESSAGE: %s\n", msg2);

close(sock);
close(new_sock);
close(new_sock2);
}
4

3 回答 3

3

您不应调用accept()已连接的套接字。一旦您在服务器中有一个连接的套接字(由 返回的套接字accept()),您应该继续读取和写入该套接字,直到连接关闭。服务器的步骤应类似于:

listen_socket = socket(...);
listen(listen_socket, ...);
connected_socket = accept(listen_socket, ...);
read(connected_socket, ...)
write(connected_socket, ...)
read(connected_socket, ...)
write(connected_socket, ...)
...

同样,一旦成功连接,客户端应该继续读取和写入套接字 - 客户端的步骤应该是:

connected_socket = socket(...);
connect(connected_socket, ...);
write(connected_socket, ...);
read(connected_socket, ...);
write(connected_socket, ...);
read(connected_socket, ...);
...
于 2012-10-25T20:52:37.400 回答
1

INADDR_ANY在服务器中工作,但您的客户端需要指定它连接到的主机。

如果两者都在同一台机器上,只需使用 127.0.0.1 或 localhost (您必须进行转换以使其格式正确)

更多信息在这里,但简短的回答是

#define INADDR_LOOPBACK 0x7f000001

接着s_address.sin_addr.s_addr = htonl (INADDR_LOOPBACK)

于 2012-10-25T20:22:37.463 回答
1

在客户端上,您尝试接受与先前连接到服务器的套接字的新连接,该套接字将绑定到系统选择的端口号。服务器从不尝试连接到客户端,因此客户端accept上的调用永远不会返回(实际上它可能会返回但有错误,因为您从不调用listen该套接字)。

为什么不使用前面步骤中使用的相同套接字执行步骤 3?如果出于某种原因您确实需要一个新套接字,则应在客户端中创建一个新套接字,而不是重用前一个套接字(或调用close前一个套接字,然后connect再次调用它)。

顺便说一句,如果您只需要 IPC,那么套接字是一种非常糟糕的方法。我建议使用 Java RMI 之类的东西。

于 2012-10-25T20:30:49.893 回答