一、问题的引入——socket的引入是为了解决不同计算机间进程间通信的问题

1.socket与进程的关系

1).socket与进程间的关系:socket   用来让一个进程和其他的进程互通信息(IPC),而Socket接口是TCP/IP网络的API接口函数。

2).进程间通信(本机内)

进程间通信(不同计算机,要联网)

2、socket与文件的关系——如何理解socket是种特殊的I/O?

1)Socket最先应用于Unix操作系统,如果了解Unix系统的I/O的话,就很容易了解Socket了,因为Socket数据传输其实就是一种特殊的I/O。

2)可对其进行文件操作

3)有文件描述符。而文件描述符的本质是一个非负整数。只是用于区分。类似的还有进程ID。

3.服务器端口与连接个数的关系

1)服务端在8088上监听,然后生成一个新的socket与client通讯。(注意:服务器端监听端口是

不变的,但socket连接可以一直生成,一个线程对应一个socket.)

同一时刻,一个端口只能建立一个连接。 

在一个端口监听,但是在监听端口的同时,生成一个等待队列,每一个来自客户端的连接都会送入等待队列中,服务器利用一定的算法进行选择相应的连接请求处理,所以在一个端口可以监听多各请求嘛。如果同时的连接过多,服务器相应每个连接的时间就会相应的变长。就会变慢。

2)QQ的实现方法就是在登陆的时候告诉服务器你已经登陆,发送消息的时候,首先你会发送一个包给服务器,服务器查看你需要发送的对方是否在线,如果在线就返回包告诉你对方在线,然后你就会和对方建立一个连接,然后直接发消息给对方,如果对方不在线,那么就会通过服务器转发你这次的消息

3)网络IO数与你的CPU数目一致将是比较好的选择(考虑到多线程多进程可以提高效率)。 

没有必要每个客户分配一个端口。绝对是一种无谓的浪费。

4.有人知道socket监听的一个端口.最多可以有多少个客户连接? 

1)listen()中有个参数,应该是确定并行连接客户数?!

2)The   maximum   length   of   the   queue   of   pending  
connections.   If   this   value   is   SOMAXCONN,   then   the  
underlying   service   provider   responsible   for   socket   s   will  
set   the   backlog   to   a   maximum   "reasonable "  
value.   There   is   no   standard   provision   to   find   out   the
  actual   backlog   value.   

3)linux2.4下,最多可以有1024个socket连接

4)同时连接请求好像是5个(是连接请求,不是连接),可保持的链接理论上是65535(2字节的SOCKET端口号),

3.Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以较为方便的编写网络上数据的传递。

5.问:现在server与client想建立socket连接,server仅知道client的IP,端口号不知道,能建立连接吗?怎么建立呢?有没有代码看看?

答:C和S是相对而言的,发起连接的一方就是C,而监听端口接受连接的一方就是S,C如果不知道S监听的端口,怎么发起连接呢,

另外,对于S而言,端口是S上各个服务的区分标志,如果用错误的端口号去连接,是不能获得正确的服务的。

client的端口是不需要指定的,Server绑定端口,然后监听,client使用server的IP和端口建立socket连接 



6.精彩问答

问:看到的文章上说“每个网络通信循环地进出主计算机的TCP   应用层。它被两个所连接的号码唯一地识别。这两个号码合起来叫做套接字.组成套接字的这两个号码就是机器的IP   地址和TCP   软件所使用的端口号。” 

又说“通过socket()函数可以创建一个套接字,然后再把它绑定到端口号...” 

那么套接字socket的概念究竟到哪里为止呢?是仅限于socket()返回的文件描述符?还是是IP和端口号的组合?如果是,那么socket()调用之后产生的套接字描述符的作用是什么呢?   套接字描述符,IP地址,端口号三者间的关系是怎样的? 

谢谢各位前辈解答。

:一个socket句柄代表两个地址对   “本地ip:port”--“远程ip:port”

:那么socket的概念到底到那里为止呢?比如,利用socket()可以产生一个套接字句柄,可是在bind()   或者   connect   ()   之前它只是一个文件描述符,和linux中其他的文件描述符一样。 

如果说socket代表一个两个地址对,那么句柄的作用是不是仅仅是在bind()   或者   connect   ()  
之后的用于区分和标记这样的地址对呢?因为这样他才能和网络的概念联系起来。这样的话,socket的意义应该是说用文件描述符描述的通信双方的IP地址和端口号地址对?(而文件描述符是区分这些地址对的标记?)

:socket为内核对象,由操作系统内核来维护其缓冲区,引用计数,并且可以在多个进程中使用。 

至于称它为“句柄”“文件描述符”都是一样的,它只不过是内核开放给用户进程使用的整数而已

问:谢谢楼上,是我没描述清楚。对于“句柄”和“文件描述符”我没有异议。 

我想我的问题是在于句柄和ip、port的关系,不知道我这样说对否: 

1.   每一个socket   本质上都是指一个ip地址和端口对 

2.   为了操作这样的地址对,使用了文件描述符 

3.   socket()函数只创建了一个普通的文件描述符,在进行bind()或者connect()之前并不能说创建了用于网络通讯的套接字 

4.   只有在进行了bind()或者connect()之后socket才被创立起来

:socket()创建了一个socket内核对象。 

accept或者connect后,才可以对socket句柄读写。因为只有在   connect或者bind,listen,accept后才会设置好socket内核对象里边的ip和端口 

二、socket和端口理解

一个socket句柄代表两个地址对 “本地ip:port”--“远程ip:port” 

在windows下叫句柄,在linux下叫文件描述符 

socket为内核对象,由操作系统内核来维护其缓冲区,引用计数,并且可以在多个进程中使用。 至于称它为“句柄”“文件描述符”都是一样的

我假定读者已经对于socket连接的建立过程和各种状态转换比较熟悉了,因为这篇文档的目的是澄清概念,而不是介绍概念。 

在使用socket编程时,我们都知道在网络通信以前首先要建立连接,而连接的建立是通过对socket的一些操作来完成的。那么,建立连接的过程大致可以分为以下几步: 

1) 建立socket套接字。 

2) 给套接字赋予地址,这个地址不是通常的网络地址的概念。 

3) 建立socket连接。 



1. 建立socket套接字。 

使用socket建立套接字的时候,我们实际上是建立了一个数据结构。这个数据结构最主要

的信息是指定了连接的种类和使用的协议,此外还有一些关于连接队列操作的结构字段

(这里就先不涉及他们了)。 

当我们使用socket函数以后,如果成功的话会返回一个int型的描述符,它指向前面那个

被维护在内核里的socket数据结构。我们的任何操作都是通过这个描述符而作用到那个数

据结构上的。这就像是我们在建立一个文件后得到一个文件描述符一样,对文件的操作都

是通过文件描述符来进行的,而不是直接作用到inode数据结构上。我之所以用文件描述

符举例,是因为socket数据结构也是和inode数据结构密切相关,它不是独立存在于内核

中的,而是位于一个VFS inode结构中。所以,有一些比较抽象的特性,我们可以用文件

操作来不恰当的进行类比以加深理解。 

如前所述,当建立了这个套接字以后,我们可以获得一个象文件描述符那样的套接字描述

符。就象我们对文件进行操作那样,我们可以通过向套接字里面写数据将数据传送到我们

指定的地方,这个地方可以是远端的主机,也可以是本地的主机。如果你有兴趣的话,还

可以用socket机制来实现IPC,不过效率比较低,试试也就行了(我没有试过)。 



2. 给套接字赋予地址。 

依照建立套接字的目的不同,赋予套接字地址的方式有两种:服务器端使用bind,客户端

使用connetc。 

Bind: 

我们都知道,只要使用IP, prot就可以区分一个tcp/ip连接(当然这个连接指的是一个

连接通道,如果要区分特定的主机间的连接,还需要第三个属性 hostname)。 

我们可以使用bind函数来为一个使用在服务器端例程中的套接字赋予通信的地址和端口。

在这里我们称通信的IP地址和端口合起来构成了一个socket地址,而指定一个socket使

用特定的IP和port组合来进行通行的过程就是赋予这个socket一个地址。 

要赋予socket地址,就得使用一个数据结构来指明特定的socket地址,这个数据结构就

是struct sockaddr。对它的使用我就不说了,因为这篇文档的目的是澄清概念而不是说

明使用方法。Bind函数的作用就是将这个特定的标注有socket地址信息的数据结构和

socket套接字联系起来,即赋予这个套接字一个地址。但是在具体实现上,他们两个是怎

么联系在一起的,我还不知道。 

一个特定的socket的地址的生命期是bind成功以后到连接断开前。你可以建立一个

socket数据结构和socket地址的数据结构,但是在没有bind以前他们两个是没有关系

的,在bind以后他们两个才有了关系。这种关系一直维持到连接的结束,当一个连接结束

时,socket数据结构和socket地址的数据结构还都存在,但是他们两个已经没有关系

了。如果你要是用这个套接字在socket地址上重新进行连接时,需重新bind他们两个。再

注明一次,我说的这个连接是一个连接通道,而不是特定的主机之间的连接。 

Bind指定的IP通常是本地IP(一般不特别指定,而使用INADDR_ANY来声明),而最主要

的作用是指定端口。在服务器端的socket进行了bind以后就是用listen来在这个socket

地址上准备进行连接。 

connect: 

对于客户端来说,是不会使用bind的(并不是不能用,但没什么意义),他们会通过

connet函数来建立socket和socket地址之间的关系。其中的socket地址是它想要连接的

服务器端的socket地址。在connect建立socket和socket地址两者关系的同时,它也在

尝试着建立远端的连接。 

3. 建立socket连接。 

对于准备建立一个连接,服务器端要两个步骤:bind, listen;客户端一个步骤:

connct。如果服务器端accept一个connect,而客户端得到了这个accept的确认,那么

一个连接就建立了。

三、客户/服务器模式模式的理解

客户/服务器模式采取的是主动请求方式:

首先服务器方要先启动,并根据请求提供相应服务:

1. 打开一通信通道并告知本地主机,它愿意在某一公认地址上(周知口,如FTP为21)接收客户请求;

2. 等待客户请求到达该端口;

3. 接收到重复服务请求,处理该请求并发送应答信号。接收到并发服务请求,要激活一新进程来处理这个客户请求(如UNIX系统中用fork、exec)。新进程处理此客户请求,并不需要对其它请求作出应答。服务完成后,关闭此新进程与客户的通信链路,并终止。

4. 返回第二步,等待另一客户请求。

5. 关闭服务器

客户方:

1. 打开一通信通道,并连接到服务器所在主机的特定端口;

2. 向服务器发服务请求报文,等待并接收应答;继续提出请求......

3. 请求结束后关闭通信通道并终止。

从上面所描述过程可知:

1. 客户与服务器进程的作用是非对称的,因此编码不同。

2. 服务进程一般是先涌纪纪户请求而启动的。只要系统运行,该服务进程一直存在,直到正常或强迫终止。

SOCKET是什么的更多相关文章

  1. socket读写返回值的处理

    在调用socket读写函数read(),write()时,都会有返回值.如果没有正确处理返回值,就可能引入一些问题 总结了以下几点 1当read()或者write()函数返回值大于0时,表示实际从缓冲 ...

  2. Socket聊天程序——Common

    写在前面: 上一篇记录了Socket聊天程序的客户端设计,为了记录的完整性,这里还是将Socket聊天的最后一个模块--Common模块记录一下.Common的设计如下: 功能说明: Common模块 ...

  3. Socket聊天程序——客户端

    写在前面: 上周末抽点时间把自己写的一个简单Socket聊天程序的初始设计和服务端细化设计记录了一下,周二终于等来毕业前考的软考证书,然后接下来就是在加班的日子度过了,今天正好周五,打算把客户端的详细 ...

  4. Socket聊天程序——服务端

    写在前面: 昨天在博客记录自己抽空写的一个Socket聊天程序的初始设计,那是这个程序的整体设计,为了完整性,今天把服务端的设计细化记录一下,首页贴出Socket聊天程序的服务端大体设计图,如下图: ...

  5. Socket聊天程序——初始设计

    写在前面: 可能是临近期末了,各种课程设计接踵而来,最近在csdn上看到2个一样问答(问题A,问题B),那就是编写一个基于socket的聊天程序,正好最近刚用socket做了一些事,出于兴趣,自己抽了 ...

  6. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  7. Android Socket连接PC出错问题及解决

    最近测试问题:Android 通过Socket链接电脑,ip和端口都是正确的,也在同一网段,可android端就是报异常如下: 解决办法:测试电脑的防火墙可能开着,在控制面板把防火墙打开即可.

  8. Linux下的C Socket编程 -- server端的继续研究

    Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...

  9. Mono 3.2.3 Socket功能迎来一稳定的版本

    由于兴趣自己业余时间一直在搞.net下面的通讯应用,mono的存在得以让.NET程序轻松运行在Linux之下.不过经过多尝试Socket相关功能在Mono下的表现并不理想.不管性能还是吞吐能力方面离我 ...

  10. Demo源码放送:打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!

    随着HTML5 WebSocket技术的日益成熟与普及,我们可以借助WebSocket来更加方便地打通BS与CS -- 因为B/S中的WebSocket可以直接连接到C/S的服务端,并进行双向通信.如 ...

随机推荐

  1. iOS开发 改变UINavigationController的UINavigationBar的高度和背景图片

    1.改变高度 自定义UINavigationBar的新类别: //UINavigationBar+BackgoundImage.h #import <Foundation/Foundation. ...

  2. 第一章 Slenium2-Java 自动化测试基础

    都是一些最基础的知识点. 一:软件测试分类 1)单元测试:单元测试(或模块测试)是对程序中的单个子程序或具有独立功能的代码段进行测试的过程.2)集成测试:集成测试是在单元测试的基础上,先通过单元模块组 ...

  3. IIS日志路径,修改存放位置,清除日志方法

    IIS存放日志文件的默认存储路径是c:\windows\system32\logfiles 我们依次打开“我的电脑”,C盘,Windows文件夹,system32文件夹,logfiles文件夹,发现里 ...

  4. linux下配置ip地址四种方法(图文)

    (1)Ifconfig命令   第一种使用ifconfig命令配置网卡的ip地址.此命令通常用来零时的测试用,计算机启动后 ip地址的配置将自动失效.具体用法如下.Ipconfig  ethx   i ...

  5. IOS开发使用YiRefresh进行刷新

    1.将YiRefresh下载后,拖进项目 YiRefresh地址:https://github.com/coderyi/YiRefresh 2.添加两个头文件 #import "YiRefr ...

  6. stm8的独立看门狗与窗口看门狗

    STM8拥有两个硬件看门狗,分别叫做独立看门狗和窗口看门狗 独立看门狗的框图如下 我们可以看到,独立看门狗的时钟来自于LSI内部低速振荡器,经过二分频到达看门狗外设单元,在经过一个七位的预分频到达计数 ...

  7. 异常捕获拒绝闪退 让应用从容的崩溃UncaughtExceptionHandler

    虽然大家都不愿意看到程序崩溃,但可能崩溃是每个应用必须面对的现实,既然崩溃已经发生,无法阻挡了,那我们就让它崩也崩得淡定点吧. IOS SDK中提供了一个现成的函数 NSSetUncaughtExce ...

  8. git 关联远程库(https协议)

    1.在oschina上新建库 2.在本地文件夹右键->"git Bash here" 3.设置全局变量: git config --global user.name &quo ...

  9. Oracle的一些命令

    sqlldr: 一般用于导入以任何后缀结束的文件,我这次就是因为要导入一张以.20160101为后缀的文件,当初简直束手无策 结合input.ctl使用,可以在DOS下使用,可以对一张表导入数十万,百 ...

  10. poi2007

    序:为什么写poi,zy说poi都是思路题目,不像hnoi妈的数据结构队..... 1.bzoj1102 题目大意:定义了一个山谷和山峰,求他们数量. 题解:这种题bfs咯,在bfs的时候记录一下相邻 ...