对于sockte简单的理解与整理

创建套接字
int serv_sock =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置 AF_INET
第二个参数指定要创建的套接字类型,流套接字类型为 SOCK_STREAM 、数据报套接字类型为 SOCK_DGRAM 、原始套接字 SOCK_RAW (WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据包以及协议首部);
第三个参数指定应用程序所使用的通信协议。此参数可以指定单个协议系列中的不同传输协议。在Internet通讯域中,此参数一般取值为0,系统会根据套接字的类型决定应使用的传输层协议。
socket返回值是一个标识符,后面的所有函数调用都使用这个标识符来描述套接字。

将套接字的目的地址与IP地址/端口号绑定起来
struct   sockaddr_in serv_addr ;//就假设这个结构是套接字上面的目的地址,具体的我也不清楚啊
memset (& serv_addr , 0 , sizeof ( serv_addr ));     //每个字节都用0填充

serv_addr . sin_family   =   AF_INET ; //使用IPv4地址,指定协议族
serv_addr . sin_addr . s_addr   = inet_addr ( "127.0.0.1" ); //具体的IP地址: inet_addr()的功能是将一个点分十进制的IP转换成一个长整数型数(u_long类型),服务端的话IP地址可以为指定为任意IP地址:INADDR_ANY
serv_addr . sin_port   = htons ( 1234 ); //端口:htons将整型变量从主机字节顺序转变成网络字节顺序, 就是整数在地址空间存储方式变为:高位字节存放在内存的低地址处。

服务端
服务端首先需要创建监听套接字
bind ( serv_sock , ( struct   sockaddr *)& serv_addr , sizeof ( serv_addr ));//将套接字与目的地址绑定起来
listen ( serv_sock , 20 );//监听套接字

客户端
注意客户端并不会创建监听套接字
connect ( sock , ( struct   sockaddr *)& serv_addr , sizeof ( serv_addr ));

然后服务端开启,等待客户端连接,然后创建一个连接套接字
这儿可以用while(true)或者for(;;)来持续监听来自客户端的连接。
struct   sockaddr_in clnt_addr ;//客户端传过来的目的地址
socklen_t clnt_addr_size   = sizeof ( clnt_addr );
int   clnt_sock   = accept ( serv_sock , ( struct   sockaddr *)& clnt_addr , & clnt_addr_size );

如果客户端有连接请求,必须使用下述函数来接受客户端的请求。

SOCKET accept(

       SOCKET               s,

       struct sockaddr FAR  *addr,

       int FAR          *addrlen

);

  addr用于存放客户端的地址,addrlen在调用函数时被设置为addr指向区域的长度,在函数调用结束后被设置为实际地址信息的长度。本函数会阻塞等待直到有客户端请求到达。

 返回值是一个新的套接字描述符,它代表的是和客户端的新的连接,这个套接字就是连接套接字,包含的是客户端的ip和port信息 ,而参数中的SOCKET   s包含的是服务器的ip和port信息 。(当然这个new_socket会从serv_sock中继承 服务器的ip和port信息,两种都有了,就组成了一个套接字对,注意服务端与客户端是通过套接字对联系的,TCP必须查看套接字对的所有4个元素(客户端/服务端的IP/port)才能确定由哪个端点接收某个达到的分组)。
 系统调用   accept()   会有点古怪的地方的!你可以想象发生   这样的事情:有人从很远的地方通过一个你在侦听   (listen())   的端口连接   (connect())   到你的机器。它的连接将加入到等待接受   (accept())   的队列   中。你调用   accept()   告诉它你有空闲的连接。它将返回一个新的套接字文   件描述符!这样你就有两个套接字了,原来的一个还在侦听你的那个端口,   新的在准备发送   (send())   和接收   (   recv())   数据。这就是这个过程! 

    也就是说,在连接建立后,客户端用发出连接的那个SOCKET向服务器发数据,是发给服务器新创建的SOCKET,而不是服务器的监听SOCKET。服务器的监听SOCKET永远只是用来接受连接请求。 这就好比你去吃饭,饭馆门口有迎宾小姐(监听SOCKET)看到你来后和你打招呼,然后(ACCEPT)找来一个新的服务员(NEW SOCKET)来接待你,然后守在门口继续监听下一个。监听的小姐走了,接待你的服务员当然不受影响。



建立连接套接字后就可以开始客户端与服务端的联系
注意send/recv 及write/read的区别,这里稍后再整理吧。
联系的话就可以干很多事情了,balabala......

服务端

char   str [] = "Hello World!" ;
write ( clnt_sock ,   str , sizeof ( str ));//通过连接套接字对发送消息

客户端

char   buffer [ 40 ];
read ( sock ,   buffer , sizeof ( buffer )- 1 );//通过连接套接字对接受消息
printf ( "Message form server: %s \n " ,   buffer );//在客户端显示来自主机的消息


最后通讯结束,关闭套接字对

close ( clnt_sock );
close ( serv_sock );//注意服务端还需要关闭监听套接字。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值