1.TCP流式套接字的编程步骤
在使用之前须链接库函数:工程->设置->Link->输入ws2_32.lib,OK!
服务器端程序:
1、加载套接字库
2、创建套接字(socket)。
3、将套接字绑定到一个本地地址和端口上(bind)。
4、将套接字设为监听模式,准备接收客户请求(listen)。
5、等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)。
6、用返回的套接字和客户端进行通信(send/recv)。
7、返回,等待另一客户请求。
8、关闭套接字。
客户端程序:
1、加载套接字库
2、创建套接字(socket)。
3、向服务器发出连接请求(connect)。
4、和服务器端进行通信(send/recv)。
5、关闭套接字。
1.accept()函数介绍
接收一个套接字中已建立的连接
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
功能参数描述
accept()
系统调用主要用在基于连接的套接字类型,比如SOCK_STREAM和SOCK_SEQPACKET
。它提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符。新建立的套接字不在监听状态,原来所监听的套接字也不受该系统调用的影响。
备注:新建立的套接字准备发送send()
和接收数据recv()
。
参数:
sockfd
, 利用系统调用socket()
建立的套接字描述符,通过bind()
绑定到一个本地地址(一般为服务器的套接字),并且通过listen()
一直在监听连接;
addr
, 指向struct sockaddr
的指针,该结构用通讯层服务器对等套接字的地址(一般为客户端地址)填写,返回地址addr的确切格式由套接字的地址类别(比如TCP或UDP)决定;若addr为NULL,没有有效地址填写,这种情况下,addrlen也不使用,应该置为NULL;
备注:addr是个指向局部数据结构sockaddr_in
的指针,这就是要求接入的信息本地的套接字(地址和指针)。
addrlen
, 一个值结果参数,调用函数必须初始化为包含addr所指向结构大小的数值,函数返回时包含对等地址(一般为服务器地址)的实际数值;
备注:addrlen是个局部整形变量,设置为sizeof(struct sockaddr_in)
。
如果队列中没有等待的连接,套接字也没有被标记为Non-blocking
,accept()
会阻塞调用函数直到连接出现;如果套接字被标记为Non-blocking
,队列中也没有等待的连接,accept()返回错误EAGAIN
或EWOULDBLOCK
。
备注:一般来说,实现时accept()为阻塞函数,当监听socket调用accept()时,它先到自己的receive_buf中查看是否有连接数据包;
若有,把数据拷贝出来,删掉接收到的数据包,创建新的socket与客户发来的地址建立连接;
若没有,就阻塞等待;
为了在套接字中有到来的连接时得到通知,可以使用select()
或poll()
。当尝试建立新连接时,系统发送一个可读事件,然后调用accept()
为该连接获取套接字。另一种方法是,当套接字中有连接到来时设定套接字发送SIGIO
信号。
返回值
成功时,返回非负整数,该整数是接收到套接字的描述符;出错时,返回-1,相应地设定全局变量errno。
先执行服务器端,再执行客户端,发现客户端出现很多‘烫烫烫’,而且接收到的ip地址为204.204.204,并非预先设定的127.0.0.1
出现这类问题的原因:
每次执行项目时,需要将其手动设定为“启动项目”,不然ctrl+F5相当于重新执行当前项目,即重复执行服务器端或客户端。
具体操作步骤如下:
1.右键项目
2.将其设置为启动项目
3.Ctrl+F5执行当前项目
首先执行服务器端,然后执行客服端。运行正常。
**说明:**由于客户端没有执行,所以服务器端的accept()函数没法正确被调用,导致出现‘烫烫烫’以及接受到的地址为‘204.204.204’