网络通信基础socket |
您所在的位置:网站首页 › socket连接流程 › 网络通信基础socket |
各位兄弟,网络编程之前,最好先学习计算机网络基础知识,至少您要知道计算机网络是怎么回事,知道ip地址和通信端口等基本概念。 一、网络通信socketsocket就是插座(中文翻译成套接字有点莫名其妙),运行在计算机中的两个程序通过socket建立起一个通道,数据在通道中传输。
socket把复杂的TCP/IP协议族隐藏了起来,对程序员来说,只要用好socket相关的函数,就可以完成网络通信。 二、socket的分类socket提供了流(stream)和数据报(datagram)两种通信机制,即流socket和数据报socket。 流socket基于TCP协议,是一个有序、可靠、双向字节流的通道,传输数据不会丢失、不会重复、顺序也不会错乱。就像两个人在打电话,接通后就在线了,您一句我一句的聊天。 数据报socket基于UDP协议,不需要建立和维持连接,可能会丢失或错乱。UDP不是一个可靠的协议,对数据的长度有限制,但是它的速度比较高。就像短信功能,一个人向另一个人发短信,对方不一定能收到。 在实际开发中,数据报socket的应用场景极少,本教程只介绍流socket。 三、客户/服务端模式在TCP/IP网络应用中,两个程序之间通信模式是客户/服务端模式(client/server),客户/服务端也叫作客户/服务器,各人习惯。 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 |