1

我正在 ubuntu 中学习套接字程序,为此我编写了以下用于服务器客户端通信的程序。该程序未打开端口。我还有一些关于服务器客户端通信的其他问题:

  • 当服务器接受客户端请求时,服务器是否在接受请求的那一刻开始从客户端读取?
  • u_connect 和 u_accept() 返回的文件描述符是否相同?(我找不到它,因为我的端口没有打开)
  • 由于我在同一台计算机上测试服务器客户端通话,我可以使用随机数作为端口吗?

我正在使用一个包含用于套接字编程的 OS 函数的包装库。

这是代码:

服务器.c

int main()
{
  char client[50];
  char buf[1024];
  u_port_t portnumber;
  portnumber = 4862;
  int fd = u_open(portnumber);
  int communFd = u_accept(fd, client, 50);
  printf("Opened com %d\n\n", communFd);
  fprintf(stderr, "\nComun fd is %d\n\n\n", communFd);
  read(communFd, buf, 1024);
  write(STDOUT_FILENO, buf, 1024);
  fprintf(stderr, "\n\nReading complete\n");
  return 0;
}

客户端.c

int main()
{
  u_port_t portnumber;
  portnumber = 4862;
  char client[] = "Alfred";
  char buf[1024];
  int communFd = u_connect(portnumber, client);
  printf("comun is %d\n", communFd);
  read(STDIN_FILENO, buf, 1024);
  write(communFd, buf, 1024);
  return 0;
}
4

3 回答 3

0

首先,我建议不要使用该包装器,因为它使用了一些非常古老的技术。我建议阅读getaddrinfobindlistenrecvsendclose以及滚动您自己的 POSIX 套接字代码。你会得到更好的理解。我还建议阅读Beej 的网络编程指南。也许一本书甚至会派上用场……

  1. 不。 read() 函数进行读取,而不是服务器。关于这一点,最好将 read() 的返回值存储在某处并找出它的重要意义。是手册,如果您像我们许多人一样相信阅读是一种比反复试验更有效的机制。
  2. 不。 u_open 似乎返回一个服务器套接字,其中 read() 不是一个有效的操作,尽管 accept() 是。u_accept 似乎返回一个对等套接字,其中 accept() 不是有效操作,尽管 read() 是。
  3. 当然,前提是端口大于 1024(小于 1024 通常需要超级用户权限),小于 65535,并且端口尚未绑定。
于 2013-01-28T13:52:32.313 回答
0

这是错误的。

read(communFd, buf, 1024);
write(STDOUT_FILENO, buf, 1024);

你应该这样做:

ssize_t r;
size_t space_left = 1024
while ((r=read(communFd, buf, space_left))>0) {
    space_left-=r;
    write(STDOUT_FILENO,buf,r);
}

因为在一次写入中发送的内容可能会通过网络分段并通过多次读取来检索。

于 2013-01-28T13:48:43.050 回答
0

当服务器接受客户端请求时,服务器是否在接受请求的那一刻开始从客户端读取?

当客户端(通过 write())发送的数据被接收到并且可以进入套接字读取缓冲区时,服务器可以读取。

u_connect 和 u_accept() 返回的文件描述符是否相同?(我找不到它,因为我的端口没有打开)

不,即使服务器端和客户端在同一个进程中运行也不会。

由于我在同一台计算机上测试服务器客户端通话,我可以使用随机数作为端口吗?

您可以绑定从 0 到 65535 的端口。从 0 到 1024 的端口已被调用known ports并已分配给特定服务IANA。我的建议是使用49152-65535范围内的端口号,但没有人禁止您使用较低的值。

如果端口被另一个进程绑定,它将返回错误代码。尝试另一个

于 2013-01-28T13:40:09.563 回答