一个关于socket网络编程的奇怪问题

litowen 2002-11-14 04:42:02
加精
在服务器端,每accept一个客户连接,就产生一个新的套接字 ,同时fork()一个新的进程,在这个新的进城中使用这个新的套接字与客户通信;而原来的套接字则在原来的进程中继续监听。
那么,这里这个新的套接字与原有的套接字端口号是一样呢?还是不一样呢?
资料上说,端口号是用来区分进程的。这里产生了一个新的进程,照理来讲,两个套接字的端口号应该不同,可是我在客户端用getpeername(或者在客户端新进程里用getsockname)却看到服务器端的新套接字与监听套接字端口号是一样的。这该如何解释?
...全文
245 41 打赏 收藏 转发到动态 举报
写回复
用AI写文章
41 条回复
切换为时间正序
请发表友善的回复…
发表回复
litowen 2002-11-18
  • 打赏
  • 举报
回复
我再去书店找找这本书吧
wwwunix 2002-11-18
  • 打赏
  • 举报
回复
To litowen(litowen):
其中分析的内容太多了,连图带解释有3页。呵呵,我想想看有没有其他办法。
另:这两本书所说的的并不矛盾,只是基于的角度不同。
litowen 2002-11-18
  • 打赏
  • 举报
回复
有始有终,最后公布一下正确的结论:
服务器端这两个socket(用于监听的socket和用于通信的socket)的端口号是一样的,相关说明见《TCp/IP详解》(译本第一卷193页)和《unix网络编程》(译本第88页,4.8 并发服务器)。
wwwunix 2002-11-18
  • 打赏
  • 举报
回复
Sorry,呵呵,其实我是与ftp协议弄混了。(正好在回答另一个关于ftp的问题。)
litowen 2002-11-18
  • 打赏
  • 举报
回复
呵呵,你知道为了你这几句话,几个晚上没睡好呢,总想搞清楚这个问题
在网上找这本书找了几天,今天终于找到了,结果和我的观点是一样的
litowen 2002-11-18
  • 打赏
  • 举报
回复
你把端口的意思理解错了,端口是端口,socket是socket(翻译做套接字),两者是不同的
wwwunix 2002-11-18
  • 打赏
  • 举报
回复
呵呵,可能是我理解错了。
litowen 2002-11-18
  • 打赏
  • 举报
回复
to:木易,你理解错了,我知道这两个socket不是同一个,
我一直想弄清楚的就是:这两个不同的socket是否使用同一个“端口号”?
我原先想如果使用同一个“端口号”,那么服务器端的两个进程不是使用的端口号是一样的么?,但是事实是他们使用的”端口号“是相同的

我一直说的是端口号,不是socket

litowen 2002-11-18
  • 打赏
  • 举报
回复
to:木易,书上好像并没有哪里说新建了一个临时端口号阿。
而且证明了我的观点是正确的,如有异意,请继续跟帖,或是加我QQ:5735933
wwwunix 2002-11-18
  • 打赏
  • 举报
回复
to litowen(litowen):
你的观点是说fork()后,服务器用来通讯的socket和监听socket是同一个呀.但实际上不是.
litowen 2002-11-18
  • 打赏
  • 举报
回复
to:木易,我现在弄不懂你为什么反驳我的观点了

我去查看了《unix网络编程》(译本第88页,4.8 并发服务器),也说明我的观点是正确的阿,是不是你理解错了
Aydge 2002-11-18
  • 打赏
  • 举报
回复
收藏
wwwunix 2002-11-17
  • 打赏
  • 举报
回复
1、用getpeername得到的端口与监听端口一样并不表示数据通讯用的端口和监听端口一样。
2、其实分析这个问题要先分清楚服务器是迭代服务还是并发服务,如果是迭代服务则用的是同一个端口;如果是并发服务则用的是不同的端口(临时端口)。见《UNIX网络编程》第88页,很详细地分析了这个问题。
litowen 2002-11-17
  • 打赏
  • 举报
回复
to:wwwunix(木易)
我一时间下载不到《UNIX网络编程》,不知道里面怎么说
你可不可以把相关的话贴上来

另外,我参考的是TCP/IP详解上的,两本书的作者都是Richard Stevens,
怎么会两本书有不同的提法?
imquestion 2002-11-17
  • 打赏
  • 举报
回复
写点分析啊,哪里是新的socket的本地端口号,本地ip的赋值,或者复制。
是总是这样呢,还是某些情况怎么样..
cai3995 2002-11-17
  • 打赏
  • 举报
回复
同意wwwunix上面所说,我把accept的那段代码贴一下好了。
/*
* For accept, we attempt to create a new socket, set up the link
* with the client, wake up the client, then return the new
* connected fd. We collect the address of the connector in kernel
* space and move it to user at the very end. This is unclean because
* we open the socket then return an error.
*
* 1003.1g adds the ability to recvmsg() to query connection pending
* status to recvmsg. We need to add that support in a way thats
* clean when we restucture accept also.
*/

asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_addrlen)
{
struct socket *sock, *newsock;
int err, len;
char address[MAX_SOCK_ADDR];

sock = sockfd_lookup(fd, &err);
if (!sock)
goto out;

err = -EMFILE;
if (!(newsock = sock_alloc()))
goto out_put;

newsock->type = sock->type;
newsock->ops = sock->ops;

err = sock->ops->accept(sock, newsock, sock->file->f_flags);
if (err < 0)
goto out_release;

if (upeer_sockaddr) {
if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) {
err = -ECONNABORTED;
goto out_release;
}
err = move_addr_to_user(address, len, upeer_sockaddr, upeer_addrlen);
if (err < 0)
goto out_release;
}

/* File flags are not inherited via accept() unlike another OSes. */

if ((err = sock_map_fd(newsock)) < 0)
goto out_release;

out_put:
sockfd_put(sock);
out:
return err;

out_release:
sock_release(newsock);
goto out_put;
}
------------------------------------
accept之后创建的socket对象是和原来的一样的,但是fork之后新进程的就是别的了。
imquestion 2002-11-16
  • 打赏
  • 举报
回复
把相关源码,和相关分析,整理一下贴出来吧。
cai3995 2002-11-16
  • 打赏
  • 举报
回复
我仔细看了一下accept()的代码

主要是这样的,他会创建一个新的socket对象,这个socket对象所有的连接信息都是原有的监听socket和所连接到的client信息,所以这个socket的所有信息都是和原来的监听socket的是一样的。
开始误会了你的意思,不好意思
litowen 2002-11-16
  • 打赏
  • 举报
回复
可否QQ交流?
5735933
cai3995 2002-11-16
  • 打赏
  • 举报
回复
但,如果现在假设这个服务器不是多进程的,只是单进程,处理一个连接时,服务器同样要创建一个新的socket,这个用于处理通信的socket和监听socket现在总该是在一个进程里了吧
--------------------------------------------------------------------
你这段话说得有问题,单进程的时候,他新创建一个socket干什么,C/S模式通信的原理就是服务器对客户端响应,所以在服务器端一直都是在listen,而不是“智能”的发现有客户要连接了,再去创建用于通信的socket。
服务器端监听的端口号和处理连接的端口号的确“不是”同一个!
与客户端建立连接的是监听的父进程,在accept之后才会creat一个新的进程来处理通信,所以看到的是父进程的端口号
加载更多回复(21)

4,356

社区成员

发帖
与我相关
我的任务
社区描述
通信技术相关讨论
社区管理员
  • 网络通信
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧