tcpip Socket编程入门

最近做了Gprs的通讯项目,下位机已经完成接手上位机的编写,属于赶鸭子上架现学现卖了。

socket入门推荐一个文件Socket函数。chm帮助文件,通过这个文件你可以快速的上手Socket编程,里边详尽的解释了函数的功能以及使用方法。

首先解释几个名词1、有连接TCP和无连接的数据报UDP,所谓有连接也就意味着每次进行数据发送的时候都要进行地址确定发送参数包含目标地址


一、基于TCP

(1)打开Socket

调用Socket函数创建或则打开Socket

socket():建立Socket。
格 式:SOCKET PASCAL FAR socket( int af,int type,int protocol );
参 数:af 目前只提供 PF_INET(AF_INET),type Socket 的型态 (SOCK_STREAM、SOCK_DGRAM),protocol 通讯协定(如果使用者不指定则设为0)
传回值:成功 - Socket 的识别码失败 - INVALID_SOCKET(呼叫 WSAGetLastError() 可得知原因)
说明:此函式用来建立一 Socket,并为此 Socket 建立其所使用的资源。 Socket 的型态可为 Stream Socket 或 Datagram Socket。
SOCK_STREAM  TCP连接  SOCK_DGRAM  UDP连接


(2)命名Socket

sockaddr_in  socket的数据结构、

首先初始化结构团体然后调用bind函数进行Socket命名

bind():指定 Socket 的 Local 位址 (Address)。
格 式:int PASCAL FAR bind( SOCKET s,const struct sockaddr FAR *name,int namelen );
参 数:s Socket的识别码 name Socket的位址值,其格式为 struct sockaddr { u_short sa_family; char sa_data[14]; }; namelen name的长度
传回值:成功 - 0 失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明:此一函式是指定 Local 位址及 Port 给某一未定名之 Socket。使用者若不在意位址或 Port 的值,那麽他可以设定位址为 INADDR_ANY,及Port 为 0;那麽Windows Sockets 会自动将其设定适当之位址及 Port(1024 到 5000之间的值),使用者可以在此 Socket 真正连接完成後,呼叫 getsockname() 来获知其被设定的值。

(3)与另一个Socket建立关联

一个UDP服务器是无需为客户端做任何准备工作因为关联是在接收数据时建立起来的 。

但是对于一个TCP的服务器通过listen函数做准备

listen():设定 Socket 为监听状态,准备被连接。
格 式:int PASCAL FAR listen( SOCKET s, int backlog );
参 数:s Socket 的识别码,backlog 未真正完成连接前(尚未呼叫 accept() 前)彼端的连接要求的最大个数
传回值:成功 - 0 失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明:使用者可利用此函式来设定 Socket 进入监听状态,并设定最多可有多少个在未真正完成连接前的彼端的连接要求。(目前最大值限制为 5, 最小值为1)
调用listen函数后需要调用accept函数或则select函数进行 数据的接收

accept函数适用于单个客户端,select函数适用于较多的客户端

accept:接受某一Socket的连接要求,以完成 Stream Socket 的连接。
格 式:SOCKET PASCAL FAR accept(SCOKET s,struct sockaddr FAR *addr,int FAR *addrlen);
参 数:s Socket的识别码;addr 存放来连接的彼端的位址; addrlen addr的长度
传回值:成功 - 新的Socket识别码 失败 - INVALID_SOCKET (呼叫 WSAGetLastError() 可得知原因)
说明:Server 端之应用程式呼叫此一函式来接受 Client 端要求之Socket 连接动作;如果Server 端之 Socket 是为 Blocking 模式,且没有人要求连接动作,那麽此一函式会Block 函式马上回覆错误。accept() 函式的答覆值为一新的 Socket,此 Socket 不可再用来接受其它的连接要求;但是原先之 Socket 仍可接受其他人的连接要求。

select():检查一或多个 Sockets 是否处於可读、可写或错误的状态。
格 式:int PASCAL FAR select( int nfds,fd_set FAR *readfds,fd_set FAR *writefds,fd_set FAR *exceptfds,const struct timeval FAR *timeout );
参 数:nfds 此参数在此并无作用,readfds 要被检查是否可读的 Sockets,writefds 要被检查是否可写的 Sockets,exceptfds 要被检查是否有错误的 Sockets,timeout 此函式该等待的时间。若为 NULL 时,表示 blocking,此函式会等到有事件发生。
传回值:成功 - 符合条件的 Sockets 总数 (若 Timeout 发生,则为 0) 失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明:使用者可利用此函式来检查 Sockets 是否有资料可被读取,或是有空间可以写入,或是有错误发生。

客户端发起关联

对于UDP的客户端

1)如果向不同的服务器发送数据采用sendto函数

sendto():< 将资料送到指定的目的地。/td>
格 式:int PASCAL FAR sendto( SOCKET s,const char FAR *buf,int len,int flags,const struct sockaddr FAR *to,int tolen );
参 数:s Socket 的识别码,buf 存放要传送的资料的暂存区,len buf 的长度,flags 此函式被呼叫的方式,to 资料要送达的位址,tolen to 的大小
传回值:成功 - 送出的资料长度失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明:此函式适用於 Datagram 或 Stream Socket 来传送资料到指定的位址。对 Datagram Socket 言,若是 datagram 的大小超过限制,则将不会送出任何资料,并会传回错误值。对 Stream Socket 言,其作用与 send() 相同;参数 to 及 tolen 在此并无作用。若是传送 (transport) 系统内之储存空间不够存放这些要传送的资料,sendto() 将会被 block 住,除非该Socket 被设定为 non-blocking 模式。使用者亦须注意 sendto() 函式执行完成,并不表示资料已经成功地送抵对方了。 flags 的值可设为 MSG_DONTROUTE(*暂不提供此功能)及 MSG_OOB 的组合. 本系统(WinKing)提供之 Windows Sockets API 介面乃是依照 1993年1月20日公布之 WINSOCK 第1.1版(如附录)中所定义之函式 (routine); 包括了30个Berkeley Software Distribution (BSD) 的函式以及16个符合 Windows Message-driven 特性的函式。
发送时将sockaddr作为发送参数


     2)第二种方法

首先初始化socket结构体

然后使用connect函数进行连接

connect():要求连接某一Socket到指定的对方。
格 式:int PASCAL FAR connect( SOCKET s,const struct sockaddr FAR *name,int namelen );
参 数:s Socket 的识别码 name 此 Socket 想要连接的对方位址 namelen name的长度
传回值:成功 - 0 失败 - SOCKET_ERROR (呼叫WSAGetLastError()可得知原因)
说明:此函式用来向对方要求建立连接。若是指定的对方位址为 0 的话,会传回错误值。当连接建立完成後,使用者即可利用此一 Socket 来做传送或接收资料之用了。

最后使用send函数进行发送

send():使用连接式的 Socket 传送资料。
格 式:int PASCAL FAR send( SOCKET s,const char FAR *buf,int len,int flags );
参 数:s Socket 的识别码,buf 存放要传送的资料的暂存区,len buf 的长度,flags 此函式被呼叫的方式
传回值:成功 - 送出的资料长度 失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明:此函式适用於连接式的 Datagram 或 Stream Socket 来传送资料。对 Datagram Socket 言,若是 datagram 的大小超过限制,则将不会送出任何资料,并会传回错误值。若是传送 (transport) 系统内之储存空间不够存放这些要传送的资料,send() 将会被 block 住,除非该 Socket 被设定为 non-blocking 模式。使用者亦须注意 send()函式执行完成,并不表示资料已经成功地送抵对方了。 flags 的值可设为 MSG_DONTROUTE(*暂不提供此功能)及 MSG_OOB 的组合.
对于UDP使用函数进行服务器的关联
recv():自 Socket 接收资料。
格 式:int PASCAL FAR recv( SOCKET s,char FAR *buf,int len,int flags );
参 数:s Socket 的识别码,buf 存放接收到的资料的暂存区,len buf 的长度,flags 此函式被呼叫的方式
传回值:成功 - 接收到的资料长度 (若对方 Socket 已关闭,则为 0) 失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明:此函式用来自连接式的 Datagram Socket 或 Stream Socket接收资料。对 Stream Socket 言,我们可以接收到目前有效的 (available)资料,但其数量不超过 len 的大小。若是此 Socket 设定 SO_OOBINLINE,且有 out-of-band 的资料未被读取,那麽只有 out-of-band 的资料被取出。对 Datagram Socket 言,只取出第一个 datagram;若是该 datagram 大於使用者提供的储存空间,那麽只有该空间大小的资料被取出,多馀的资料将遗失,且回覆错误的讯息。 flags 的值可为 MSG_PEEK、MSG_OOB(*暂不提供此功能)的组合.



(4)Socke之间进行数据的接收与发送

无论是udp还是tcp都需要调用connect函数进行发送数据准备

udp通过connect获得socket发送的地址

tcp通过connect建立虚电路


(5)关闭Socket

closedsocket

closesocket():关闭某一Socket
格 式:int PASCAL FAR closesocket( SOCKET s );
参 数:s Socket 的识别码
传回值:成功 - 0 失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)
说明:此一函式是用来关闭某一 Socket。若是使用者原先对要关闭之 Socket 设定 SO_DONTLINGER,则在呼叫此一函式後,会马上回覆,但是此一 Sokcet 尚未传送完毕的资料会继续送完後才关闭。若是使用者原先设定此 Socket 为 SO_LINGER,则有两种情况: (a) Timeout 设为 0 的话,此一 Socket 马上重新设定 (reset),未传完或未收到的资料全部遗失。 (b) Timeout 不为 0 的话,则会将资料送完,或是等到 Timeout 发生後才关闭。
部分关闭连接使用shoutdown


shutdown():停止 Socket 接收/传送的功能
格 式:int PASCAL FAR shutdown( SOCKET s, int how );
参 数:s Socket 的识别码,how 代表该停止那些动作的标帜
传回值:成功 - 0 失败 - SOCKET_ERROR (呼叫 WSAGetLastError()可得知原因)
说明:此函式用来停止 Socket 的後续接收或传送的功能。若 how 的值为 0,则不再接收资料。若 how 的值为 1,则不再允许传送资料。若 how 的值为 2,则不再接收且不再传送资料。 shutdown() 函式并没有将 Socket 关闭,所以该 Socket 所占用之资源必须在呼叫closesocket() 之後才会释放。




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值