首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >套接字: TCP和UDP连接(C语言)

套接字: TCP和UDP连接(C语言)
EN

Stack Overflow用户
提问于 2020-01-12 20:50:34
回答 1查看 807关注 0票数 1

我有一个进程,它必须建立一个服务器来接受TCP连接,并创建一些子进程来完成这项工作。我创建一个TCP套接字(不监听、绑定或接受),然后创建叉。我有以下问题:

如果我将该套接字绑定到一个端口并侦听该端口,那么该套接字也会在这两个调用之前分叉,侦听并绑定到同一个端口吗?如果我在套接字上使用

  1. ,并且套接字接受连接并链接到客户端套接字:分叉的套接字也会连接到那个客户端套接字吗?

我知道fd表是父亲和孩子之间共享的,但是我不知道父亲进程中发生在套接字上的任何更改是否也会发生在孩子身上。

  1. 可以使用为TCP连接打开的套接字作为TCP接收方和UDP发送方吗?
  2. 可以使用为TCP连接打开的套接字作为UDP接收方和TCP发送方吗?如果有为TCP连接打开的套接字,则
  3. :我可以使用sendto作为最后2个参数为空吗?我在在线手册中发现,对于基于连接的套接字,可以跳过最后两个参数,但我不知道我是否正确理解它。如果这是可能的话,我希望子程序能够在不知道recvfrom地址的情况下将数据报回复发送给用recvfrom等待的客户端。
  4. 可以用TCP在客户端套接字上使用最后2个参数为NULL吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-12 22:17:20

如果我将该套接字绑定到一个端口并侦听该端口,那么该套接字是否也会在这两个调用之前进行分叉,侦听并绑定到同一个端口?

一旦您有了一个文件描述符(如socketaccept创建的),对该文件描述符的更改将反映在该描述符在所有进程中的克隆中。

由于不能绑定套接字两次,所以可以使用以下内容验证我的声明。(它是用Perl编写的,但是C程序员应该能够毫无问题地阅读它。die抛出一个异常,$!strerror(errno)$!{EINVAL}等效于errno == EINVAL)。

代码语言:javascript
运行
复制
#!/usr/bin/perl

use 5.014;
use warnings;

use Socket qw( pack_sockaddr_in AF_INET SOCK_STREAM INADDR_ANY SOMAXCONN );

socket(my $socket, AF_INET, SOCK_STREAM, 0)
   or die("socket: $!\n");

defined( my $pid = fork() )
   or die("fork: $!\n");

if (!$pid) {
   bind($socket, pack_sockaddr_in(0, INADDR_ANY))
      or die("bind: $!\n");
   listen($socket, SOMAXCONN)
      or die("listen: $!\n");
   exit;
}

waitpid($pid, 0) > 0
   or die("waitpid: $!\n");

if (bind($socket, pack_sockaddr_in(0, INADDR_ANY))) {
   say "Socket bound again. bind doesn't transcend processes.";
} else {
   if ($!{EINVAL}) {
      say "Socket already bound. bind transcends processes.";
   } else {
      die("bind in parent: $!\n");
   }
}

输出:

代码语言:javascript
运行
复制
Socket already bound. bind transcends processes.

如果我在套接字上使用

,而套接字接受连接并链接到客户端套接字:分叉的套接字也会连接到那个客户端套接字吗?

不是的。这个问题的前提是accept创建的套接字与调用accept的套接字之间存在链接/连接,但是没有任何这样的链接/连接(在任何进程中)。

3.是否可以使用为TCP连接打开的套接字作为TCP接收方和UDP发送方?

4.是否可以使用为TCP连接打开的套接字作为UDP接收方和TCP发送方?

不是的。套接字要么是TCP套接字,要么是UDP套接字。不能通过TCP套接字发送/接收UDP数据包,也不能通过UDP套接字发送/接收TCP数据包。根本没办法试一试。

但是,TCP和UDP端口是独立的,因此您可以同时使用TCP端口1234和UDP端口1234 (使用两个不同的套接字)。

5.如果我有一个为TCP连接打开的套接字:我是否可以使用sendto与最后2个参数为NULL,而不存在任何问题?

是。可以在TCP套接字上调用send,对于最后两个参数,send是用带有NULL0sendto定义的。

根据我的(GNU/Linux)系统上的man 2 send

send(sockfd, buf, len, flags);等同于sendto(sockfd, buf, len, flags, NULL, 0);

实际上,必须使用TCP套接字将最后两个参数设置为NULL0

根据我的(GNU/Linux)系统上的man 2 sendto

如果在连接模式(SOCK_STREAMSOCK_SEQPACKET)套接字上使用sendto(),则忽略参数dest_addraddrlen (当它们不是NULL0时,可能返回错误EISCONN )。

6.我可以在客户端套接字上使用TCP将recvfrom与最后2个参数NULL连接起来吗?

是。可以在TCP套接字上调用recv,并为最后两个参数用带有NULLrecvfrom定义recv

根据我的(GNU/Linux)系统上的man 2 recv

recv(sockfd, buf, len, flags);等同于recvfrom(sockfd, buf, len, flags, NULL, NULL);

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59708009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档