利用socket实现Windows与Linux平台间的网络通信

摘要: 介绍了socket的工作原理,构建出一个适用于Windows和Linux操作系统的、跨平台的网络通信程序,并给出设计原理和开发步骤。整个系统采用客户机/服务器(C/S)模型,在Windows系统中,socket程序利用Visual C#语言编写。Linux系统中的socket程序调用select()函数,则该套接字自动设置为非阻塞方式,从而提高了程序的执行效率。经测试,通信两端的进程能够通过各自的套接字收发消息,从而实现了Windows与Linux平台间的通信。(套接字、跨平台网络通信、客户机/服务器、select()函数)

在工业生产中,人们常把稳定性高的Linux系统运用到工业控制领域,以此来提高控制系统的性能。基于Windows平台开发的软件使用方便,因此工程中的应用软件大多数是以Windows为平台开发的。在一个工业系统中,人们需要同时使用Windows和Linux两种操作系统。为了使两个不同的操作系统能够协同工作并互相传递消息,需要在两者间进行通信。
在日常工作中,Windows作为PC机的操作平台被广泛使用,而Linux也以其开放的优势逐渐被用户采用。在两种系统被普遍使用的前提下,如何实现资源共享就成了一个重要的研究课题,需要实现两个平台间的互相通信以达到资源共享的目的。
基于以上两点,实现Windows与Linux平台间的网络通信有着重要的研究意义。本文通过socket(套接字)编程实现两个系统间的通信,socket是对应TCP/IP协议的最典型的应用开发接口,它提供了不同主机间进程通信的端点。本文阐述了套接字的编程原理,并举例说明如何开发Linux和Windows系统之间的网络通信程序。

1 socket基本原理
1.1 基本socket函数
 socket通信涉及的基本函数有:
     (1)创建套接字
    sockfd=socket(domain, type, protocol);参数domain指定socket地址簇类型,type为套接字类型,protocol指明socket请求的协议,sockfd为套接字返回的文件描述符。
    (2)绑定套接字与本地地址信息
    bind(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr));该函数将本地主机地址以及端口号与所创建的套接字绑定起来。
    (3)监听连接
    listen(sockfd,backlog);此函数表示服务器愿意接收连接,backlog指队列中允许的最大排队请求的个数。
     (4)建立连接
    connect(sockfd,(struct sockaddr*) &server_addr,sizeof(struct sockaddr));connect用于建立连接,server_addr是保存着服务器IP地址和端口号的数据结构struct sockaddr。
     (5)接收连接请求
    accept(sockfd,(struct sockaddr*) &client_addr,sizeof(struct sockaddr));用于接收客户机发来的连接请求。
     (6)发送数据
    send(sockfd,msg,len,flags);将len字节的数据msg发送出去,flags通常为0。
    (7)接收数据
    recv(sockfd,buf,len,flags);从套接字缓冲区buf中读取len字节长度的数据。
     (8)关闭套接字
    close(sockfd);用于关闭套接字连接。
1.2 socket通信过程
套接字编程采用客户机/服务器(C/S)模式,连接成功后,双方可以进行通信。通信过程如图1所示。
利用socket实现Windows与Linux平台间的网络通信_第1张图片


2 软件设计
为避免使用两台计算机的麻烦,在Windows7系统的PC上安装虚拟机,虚拟机的操作系统是Linux。这样就可以在一台PC上进行通信测试,主机为Windows平台,虚拟机为Linux平台。
整个系统采用客户机/服务器(C/S)模型,将Linux平台作为服务器端,其IP地址为10.33.17.127,端口号为3352。将Windows平台作为客户机端,其IP地址为10.33.17.126。
2.1 Linux平台软件设计
2.1.1 响应连接
分别调用socket()、bind()、listen()和accept()来监听客户机端的连接请求并与之连接。
2.1.2 select函数[4]的使用
select可以完成非阻塞操作,即进程执行此函数时不必等待事件发生。它能够监视select返回的文件描述符的变化情况,通过返回值来判断select函数的执行情况。
首先定义一个集合变量fd_set rfds,分别将标准输入句柄0和当前连接句柄client_fd加入到集合中。先令maxfd为0,再比较client_fd与maxfd的大小,将两者中较大的值赋给maxfd,即将文件描述符的最大值赋予maxfd。设置最大等待时间tv.tv_sec=1,tv.tv_usec=0。
retval=select(maxfd+1,&rfds,NULL,NULL,&tv),通过返回值retval判断文件的读写情况。若retval为-1,则出错;若retval为0,则继续等待;若retval为正值,则文件可读写,可以执行接下来的发送和接收消息的操作。
2.1.3 发送与接收消息
if(FD_ISSET(0,&rfds))用来检查指定文件描述符0是否在该集合rfds中,若满足则执行发送操作。fgets(buf,MAXBUF,stdin)表示将键盘输入的至多MAXBUF个字符的stdin送到buf中,摁下“Enter”键后即可发送。
同理,对于是否接收消息通过if (FD_ISSET(client_fd,&rfds))来判断。
2.1.4 断开连接
若要断开连接,则输入“quit”。通过命令if(!strncasecmp(buf,"quit",4))来判断输入的内容是否为quit。连接断开后,显示框显示“Client has terminated the communication.”。
2.2 Windows平台软件设计
在Windows系统中,使用C#语言来编写socket程序。打开Microsoft Visual Studio 2010,新建一个“Windows窗体应用程序”的项目。在窗体中添加两个button控件,分别为button1(连接)和button2(发送)。并添加4个textBox控件,分别为textBox1(消息显示框)、textBox2(消息输入框)、textBox3(服务器IP地址输入框)和textBox4(服务器端口号输入框)。
2.2.1 请求连接
新建socket,Server和nPort分别表示服务器IP地址和端口号,通过命令socket.Connect(ServerIP,nPort)来连接服务器。
2.2.2 发送与接收消息
定义发送的字符串为Message,将消息输入框textBox2中的内容指定为Message。通过发送命令socket.Send(System.Text.Encoding.Default.GetBytes(Message))进行消息发送。
新建一个byte数组byte[] RecvBuffer,通过socket.Receive(RecvBuffer)将接收到的内容存放到RecvBuffer中。接收成功后,将接收到的内容显示在消息显示框中。

3 运行结果与分析
3.1 编译并执行Linux端程序
gcc server_socket.c-o server_scoket
 ./server_socket 3352 Server
 此时,服务器端程序准备就绪,等待客户端请求连接。
3.2 启动Windows端的连接
  打开Microsoft Visual Studio 2010软件,点击“启动调试”键后弹出窗体界面。点击窗体界面中的“连接”键后,客户机端能够成功连接服务器端。
3.3 实现互相通信
连接成功后,服务器端和客户机端可以自由发送消息。如图2所示,Windows系统中,在窗体界面的“消息输入框”中输入消息,点击“发送”后即可发送。在Linux终端中,输入要发送的消息,点击“Enter”键后进行发送。如图3所示。
利用socket实现Windows与Linux平台间的网络通信_第2张图片
利用socket实现Windows与Linux平台间的网络通信_第3张图片
3.4 结果分析
结果表明,服务器端和客户机端在成功连接后能够进行通信。在Linux系统中,通信结果在终端显示。在Windows系统中,通信结果在窗体界面中显示。经测试,两个平台间能够完成无数次的收发操作。若要结束通信,在Linux终端中键入“quit”,即断开连接。
本文阐述了Windows与Linux系统的网络传输设计方法,双方采用TCP/IP协议,运用socket 接口来开发网络通信程序。Windows平台利用C#编写socket程序,并通过窗体界面显示通信过程。Linux平台中的socket程序调用select函数,实现非阻塞操作。套接字使得连接在通信两端的进程,能够通过各自的套接字收发消息,从而实现了两个平台间的全双工通信。目前的通信程序只能传送字符串,要真正实现两个系统之间的资源共享与消息传递,还需要它们之间能够传送文件、照片及视频等大数据量的信息,这将是下一阶段的研究重点。

你可能感兴趣的:(网络)