我正在尝试在服务器和客户端之间发送/接收消息。我的服务器上当前有一个存储char值的结构。我正在尝试将此值传递给我的客户。请参阅以下内容:
tileInfo->tiles[user_cords_x][user_cords_y].identifier = '+'; // Char i want to pass
write_client_msg(cli_sockfd, &tileInfo->tiles[user_cords_x][user_cords_y].identifier);
/* Writes a message to a client socket. */
void write_client_msg(int cli_sockfd, char * msg)
{
int n = write(cli_sockfd, msg, strlen(msg));
if (n < 0)
error("ERROR writing msg to client socket");
}
在我的客户端上,我收到以下信息:
char *msg;
char identity = read(sockfd, msg, 1);
printf("This is the value: %d \n", identity);
当前我得到的输出是This is the value: 1
。我是套接字新手,不完全理解传递字符。有人可以解释一下,告诉我如何将“ +”传递给我的客户端吗?
答案 0 :(得分:1)
您的代码有几个错误。
在服务器端,此代码:
write_client_msg(cli_sockfd, &tileInfo->tiles[user_cords_x][user_cords_y].identifier);
很明显identifier
是单个char
,否则代码将无法编译。在这种情况下,在strlen()
内使用write_client_msg()
是错误的,因为在传递指向单个msg
的指针时char
将没有空终止符。如果不仅仅因为访问无效内存而导致崩溃,您最终将把垃圾传输给另一方。
然后,在客户端,您要将未初始化的msg
指针传递给read()
。而且,您正在显示read()
的返回值,这是实际接收到的字节数。这就是为什么您的显示器上显示1
的原因,因为您要求接收1个字节。
要正确发送和接收identifier
,您将需要以下类似内容:
void write_client_msg(int sockfd, char *msg, size_t msg_len)
{
int n = write(sockfd, msg, msg_len);
if (n < 0)
error("ERROR writing msg to client socket");
}
...
write_client_msg(cli_sockfd, &tileInfo->tiles[user_cords_x][user_cords_y].identifier, 1);
char identity;
int n = read(sockfd, &identity, 1);
if (n < 0)
error("ERROR reading identity from client socket");
else if (n == 0)
error("DISCONNECTED while reading identity from client socket");
else
printf("This is the value: %c \n", identity);
话虽这么说,一种更好的解决方案是使write_client_msg()
在发送msg_len
之前先发送msg
。特别是由于write_client_msg()
不知道它正在发送哪种数据。然后,客户端可以读取msg_len
来知道要为msg
读取多少字节,然后根据需要处理msg
。
此外,write()
和read()
返回的字节数少于请求的字节数,因此您需要循环调用它们以确保您实际发送/接收所有内容。
例如:
int write_all(int sockfd, void *data, size_t data_len)
{
char *d = (char*) data;
while (data_len > 0)
{
int n = write(sockfd, d, data_len);
if (n < 0)
return n;
d += n;
data_len -= n;
}
return 1;
}
void write_client_msg(int sockfd, char *msg, size_t msg_len)
{
uint32_t len = htonl(msg_len);
int n = write_all(sockfd, &len, sizeof(len));
if (n == 1)
n = write_all(sockfd, msg, msg_len);
if (n < 0)
error("ERROR writing msg to client socket");
}
...
write_client_msg(cli_sockfd, &tileInfo->tiles[user_cords_x][user_cords_y].identifier, 1);
int read_all(int sockfd, void *data, size_t data_len)
{
char *d = (char*) data;
while (data_len > 0)
{
int n = read(sockfd, d, data_len);
if (n <= 0)
return n;
d += n;
data_len -= n;
}
return 1;
}
char *read_server_msg(int sockfd)
{
uint32_t len;
int n = read_all(sockfd, &len, sizeof(len));
if (n <= 0)
return NULL;
len = ntohl(len);
char *msg = malloc(len+1);
if (!msg)
return NULL;
n = read_all(sockfd, msg, len);
if (n <= 0) {
free(msg);
return NULL;
}
msg[len] = '\0';
return msg;
}
...
char *msg = read_server_msg(sockfd);
if (!msg)
error("ERROR reading msg from client socket");
else {
printf("This is the value: %s \n", msg);
free(msg);
}
答案 1 :(得分:-1)
正确的解决方案(基于您的代码)将是:
private void updateList() {
FirebaseRecyclerOptions<User> userOptions = new FirebaseRecyclerOptions.Builder<User>()
.setQuery(counterRef,User.class)
.build();
adapter = new FirebaseRecyclerAdapter<User, ListOnlineViewHolder>(userOptions) {
@Override
protected void onBindViewHolder(@NonNull ListOnlineViewHolder viewHolder, int position, @NonNull final User model) {
if(!model.getEmail().equals(FirebaseAuth.getInstance().getCurrentUser().getEmail()))
viewHolder.txtEmail.setText(model.getEmail()+"(me)");
else
viewHolder.txtEmail.setText(model.getEmail());
//we need implement item click f recycler view
viewHolder.itemClickListener=(ItemClickListener)(view, position);{
//if model is current user, not set click event
if (!model.getEmail().equals(FirebaseAuth.getInstance().getCurrentUser().getEmail())) {
Intent map = new Intent(ListOnline.this, MapTracking.class);
map.putExtra("email", model.getEmail());
map.putExtra("lat", mLastLocation.getLatitude());
map.putExtra("lng", mLastLocation.getLongitude());
startActivity(map);
}
答案 2 :(得分:-3)
已解决:
char *msg;
msg = (char*) malloc (1);
read(sockfd, msg, 1);
printf("Sent received: %s \n", msg);