imjacob的专栏

首页博文目录订阅
正 文

socket中accept函数的更深理解

(2009/11/17 21:12)

按: 网络编程也 进行了一段时间了,最近在看ruby的时候,发现 基本的套接字函数理解都有问题。要反思啊

 

=================================================

BSD中的 socket编程中 ,tcp 服务器端 accept的原型是这样的

int accept(int sockfd, void *addr, int *addrlen);

但返回值是什么呢 ?

是一个new_fd,新的套接字描述符,它代表的是 和客户端的新的连接 。

可以把它理解成是一个客户端的socket(??),这个socket包含的是客户端的ip和port信息 。(当然这个new_fd会从sockfd中继承 服务器的ip和port信息,两种都有了

而参数中的sockfd包含的是服务器的ip和port信息 。

于是之后的send和recv函数中的fd都是指这个 new_fd,也就是
int send(int new_fd, const void *msg, int len, int flags);
int recv(int new_fd, void *buf, int len, unsigned int flags);

即参数其实都是目标fd(就是记录了客户端的信息 ),说明服务器是从客户端接收或者发送给客户端的。这个和文件的操作FILE *fp =fopen(); fwrite(fp,xx,xx,xx);是差不多的,这里的fp代表的也是目标即目标文件名。

而我之前理解成 就是返回一个新的描述符 ,这个描述符还是代表了服务器端,然后客户端和这个新的描述符通信,是为了进程而进程。 这样造成的后果就是,对于 new_fd的port是多少呢 ,搞不清了。如果是和sockfd一样,那还叫新的吗?如果不和sockfd一样,那会是另外一个数字,那怎么解释 http服务器只有一个端口 80呢?


==========================================

这样,客户端的 connect函数 ,
int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
这里的sockfd 就把客户端的ip和port  ,服务器的ip和port信息都有了。所以之后的 send(),recv()都有信息了。

 

===============================================================

今天网上看到一篇帖子和我说的差不多。原文在http://bbs.pfan.cn/post-270023.html  (问一下关于socket的几个问题)

Q:
accept接受socket的描述符作为参数,之后返回另一个socket描述符,那这两个socket有什么区别和联系? 假如调用之前的socket绑定在8000端口,那返回之后的socket是不是也绑定在8000端口?一个端口可以绑定几个socket吗?

这个顺便问问, 在shell脚本中,我想用变量存起命令执行后的字串,应该怎么做?

Q: socket看成IP+端口,server的IP x:8000 (应为8080??by imjacob)是那个在listen的socket做参数传给accept,从这个socket可以得到一些访问它的英特网用户,它们就是那个返回的socket,比如y:4321(??by imjacob),然后你可以用其它的线程和这个socket通信,收和发,它代表已经连接的链路。画个图


                   server [ 192.168.1.128 : 8080 ] state: listening



        |            |            |       ......              |
    client1      client2       client3     ......     clientx [ 10.0.1.255 : 1234 ]


一开始是client知道server的IP,或者用DNS解析后的IP,和某种协议固定的端口号,然后发送连接请求,client会一直用那个socket[ 192.168.1.128 : 8080 ]和server通信(可能协议还会建立其它链路,只一般情况),而server会用client的IP和某个端口进行通信,那就是accept返回的socket。

我们打电话的时候,都要拿着一头的话筒,那个话筒连接着对方(技术细节忽略),通话的双方都拿着和对方相连的话筒,这两个socket是不同的,都代表着对方。

不是一个端口可以绑定几个socket就只有一个IP的计算机来说,终端,它可以有很多服务,每一个服务或者进程会使用不同的端口,比如同一个办公楼层不同的房间号码,在应用层,能够通信的对象变成了‘进程’,只考虑进程间的网络通信,而端口就是用来分发给进程用的,OS收到了TCP包,把端口号取出来,再送到相应的进程并通知它进行处理。 accept返回的,收到的socket是对方client的IP+端口号,和你自己的进程占用的端口号不相关,这些端口号是确保你发送的信息会正确的到达对方的机器上的正确的进程中去。

评 论
3楼 52RD网友 发表于 2011/9/9 13:38 回复
这个顺便问问, 在shell脚本中,我想用变量存起命令执行后的字串,应该怎么做? my_var=`pwd`
2楼 52RD网友 发表于 2009/12/18 17:46 回复
哈哈,1楼的你想笑死我啊
1楼 52RD网友 发表于 2009/12/12 14:54 回复
不知道你说什么 怎么看都像一个神经病
博 主
进入imjacob的首页
博客名称:雅克的一府
日志总数:514
评论数量:901
访问次数:1870050
建立时间:2006/11/23 20:52
导 航
公 告
Locations of visitors to this page 本博客主要用于个人学习与资料收藏。当然大家应该读了之后也能学到不少东西。其中大多数资料都是来自网络,我转载时尽可能地表明文章出处与原作者姓名,但由于很多资料经多人转载,已不清楚原作者信息与出处,所以未表明相关…
评 论
链 接

ARM+LINUX 嵌入式博客
http://blog.chinaunix.net/u1/58780/index.html

嵌入式软件
http://blog.csdn.net/embeddedsoft

诚诚恳恳做人踏踏实实编程
http://blog.sina.com.cn/u/1244756857 

和我风格相似的一个blog
http://blogger.org.cn/blog/m…