对accept()做了什么很疑惑,对于send(),recv()函数的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+端口号,和你自己的进程占用的端口号不相关,这些端口号是确保你发送的信息会正确的到达对方的机器上的正确的进程中去。