网络通信基础socket

您所在的位置:网站首页 socket连接流程 网络通信基础socket

网络通信基础socket

#网络通信基础socket| 来源: 网络整理| 查看: 265

各位兄弟,网络编程之前,最好先学习计算机网络基础知识,至少您要知道计算机网络是怎么回事,知道ip地址和通信端口等基本概念。

一、网络通信socket

socket就是插座(中文翻译成套接字有点莫名其妙),运行在计算机中的两个程序通过socket建立起一个通道,数据在通道中传输。

     image.png

socket把复杂的TCP/IP协议族隐藏了起来,对程序员来说,只要用好socket相关的函数,就可以完成网络通信。

二、socket的分类

socket提供了流(stream)和数据报(datagram)两种通信机制,即流socket和数据报socket。

流socket基于TCP协议,是一个有序、可靠、双向字节流的通道,传输数据不会丢失、不会重复、顺序也不会错乱。就像两个人在打电话,接通后就在线了,您一句我一句的聊天。

数据报socket基于UDP协议,不需要建立和维持连接,可能会丢失或错乱。UDP不是一个可靠的协议,对数据的长度有限制,但是它的速度比较高。就像短信功能,一个人向另一个人发短信,对方不一定能收到。

在实际开发中,数据报socket的应用场景极少,本教程只介绍流socket。

三、客户/服务端模式

在TCP/IP网络应用中,两个程序之间通信模式是客户/服务端模式(client/server),客户/服务端也叫作客户/服务器,各人习惯。

image.png

1、服务端的工作流程

1)创建服务端的socket。

2)把服务端用于通信的地址和端口绑定到socket上。

3)把socket设置为监听模式。

4)接受客户端的连接。

5)与客户端通信,接收客户端发过来的报文后,回复处理结果。

6)不断的重复第5)步,直到客户端断开连接。

7)关闭socket,释放资源。

服务端示例(server.cpp)

/*  * 程序名:server.cpp,此程序用于演示socket通信的服务端  * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include  #include  #include  #include  #include  #include  #include  #include    int main(int argc,char *argv[]) {   if (argc!=2)   {     printf("Using:./server port\nExample:./server 5005\n\n"); return -1;   }     // 第1步:创建服务端的socket。   int listenfd;   if ( (listenfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; }     // 第2步:把服务端用于通信的地址和端口绑定到socket上。   struct sockaddr_in servaddr;    // 服务端地址信息的数据结构。   memset(&servaddr,0,sizeof(servaddr));   servaddr.sin_family = AF_INET;  // 协议族,在socket编程中只能是AF_INET。   servaddr.sin_addr.s_addr = htonl(INADDR_ANY);          // 任意ip地址。   //servaddr.sin_addr.s_addr = inet_addr("192.168.190.134"); // 指定ip地址。   servaddr.sin_port = htons(atoi(argv[1]));  // 指定通信端口。   if (bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) != 0 )   { perror("bind"); close(listenfd); return -1; }     // 第3步:把socket设置为监听模式。   if (listen(listenfd,5) != 0 ) { perror("listen"); close(listenfd); return -1; }     // 第4步:接受客户端的连接。   int  clientfd;                  // 客户端的socket。   int  socklen=sizeof(struct sockaddr_in); // struct sockaddr_in的大小   struct sockaddr_in clientaddr;  // 客户端的地址信息。   clientfd=accept(listenfd,(struct sockaddr *)&clientaddr,(socklen_t*)&socklen);   printf("客户端(%s)已连接。\n",inet_ntoa(clientaddr.sin_addr));     // 第5步:与客户端通信,接收客户端发过来的报文后,回复ok。   char buffer[1024];   while (1)   {     int iret;     memset(buffer,0,sizeof(buffer));     if ( (iret=recv(clientfd,buffer,sizeof(buffer),0))h_length);   if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0)  // 向服务端发起连接清求。   { perror("connect"); close(sockfd); return -1; }     char buffer[1024];     // 第3步:与服务端通信,发送一个报文后等待回复,然后再发下一个报文。   for (int ii=0;iiclose

客户端函数调用的流程是:socket->connect->send/recv->close

其中send/recv可以进行多次交互。

六、课后作业

1)把client.cpp和server.cpp抄下来,编译运行,试试修改参数再运行。

2)client.cpp和server.cpp程序中,有些代码不能动,有些代码可以动,把能动的都动一下,就算是抄代码,也要抄个明白。

3)服务端的accept函数会阻塞,阻塞是专业名词,即等待,可以用代码测试一下。

4)不管是服务端还是客户端recv函数也会阻塞,可以用代码测试一下。

5)修改client.cpp和server.cpp,实现点对点的聊天功能,用户在客户端输入一个字符串,然后发送给服务端,服务端收到客户端的报文后,也提示用户输入一个字符串,返回给客户端,如果服务端收到客户端的报文是“bye”通信结束。

6)如果以上作业都能完成,建议再把本文章的内容再看一次,对文章开始部分的理论知识将有新的理解。

七、版权声明

C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。

来源:C语言技术网(www.freecplus.net)

作者:码农有道



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3