欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

主机(client)与ubuntu虚拟机(server)的通信(Version 1.0)

程序员文章站 2022-07-14 09:30:27
...

       以下两个程序实现了ubuntu虚拟机 -> 主机VS2017的数据通信. 虽然实现了数据的通信, 但是有个问题值得我们注意: 当建立连接后, 我们在一段时间后关闭client程序(VS2017), 此时ubuntu端的send()函数会阻塞------这样一来, 每当我们在VS2017端关闭一次客户端程序, ubuntu端就会多一个浪费内存空间的服务端处理进程: 当VS2017端频繁开启关闭客户端程序, ubuntu端的压力会很大. 所以, 接下来如何应对客户端程序关闭变成了主要问题(应对方案将在Version 1.1中发布). 

       现在以下两个程序已经能够实现将ubuntu虚拟机端产生的数据送到主机VS 2017端.

//server.c 服务端
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <arpa/inet.h> 
#include <time.h>
#define SERVPORT 3333
#define BACKLOG 10
int random_number()//generating a random number
{
    int a;
    srand((unsigned)time(NULL));
    a = rand();
    return a;
}
int main()
{	
    int sockfd,client_fd;
    int value;
    int recvbytes;
    int sin_size;
    char buf[50];
    struct sockaddr_in my_addr;    
    struct sockaddr_in remote_addr; 
    sockfd = socket(AF_INET, SOCK_STREAM, 0);//建立socket --
    my_addr.sin_family=AF_INET;//AF_INET地址族
    my_addr.sin_port=htons(SERVPORT);//设定端口号(host -> networks)
    my_addr.sin_addr.s_addr = INADDR_ANY;//32位IPv4地址
    bzero(&(my_addr.sin_zero),8); //置前8个字节为0
    if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) 
     {
  	  perror("bind 出错!");		
	  exit(1);	
     }
    if (listen(sockfd, BACKLOG) == -1) //监听socket连接,设置队列中最多拥有连接个数为10  --
     {	
	  perror("listen 出错!");	
        exit(1);     
     }
    while(1)
     {
	  sin_size = sizeof(struct sockaddr_in);//记录sockaddr_in结构体所占字节数
	  if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1) //accept()缺省是阻塞函数,阻塞到有连接请求为止 --
          {	
	      perror("accept error");		
	      continue;		
	  }
	  printf("收到一个连接来自: %s\n", inet_ntoa(remote_addr.sin_addr));
	  if (!fork()) 
          {
		//test 1
		//recv(client_fd, buf, 25, 0);
		//printf("%s\n", buf); 	  
	
		//test 2
		//send(client_fd, "12345", 5, 0);	
			
		//sending pieces of message to client
		while(1)
		{
		    //generating a random number and sending it to the host

		    value = random_number();

       	            sprintf(buf, "%d", value);//int to string

		    //every one second client sends a random number converted to string to client
			
		    send(client_fd, buf, (int)strlen(buf), 0);
		    
		    sleep(1);
		}
		
            	close(client_fd);	
            	exit(0);		
          }
	  close(client_fd);
     }
} 
//client 客户端 Visual Studio 2017 professional
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace data_receiving
{
    class Program
    {
        public static Socket ClientSocket;
        public static String IP = "192.168.239.132";//ubuntu虚拟机(server端)的IP地址
        public static void receive_message()//接收ubuntu虚拟机发来的数据
        {
            int port = 3333;//通信端口

            IPAddress ip = IPAddress.Parse(IP);  //将IP地址字符串转换成IPAddress实例
            ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//使用指定的地址簇协议、套接字类型和通信协议
            IPEndPoint endPoint = new IPEndPoint(ip, port); // 用指定的ip和端口号初始化IPEndPoint实例
            ClientSocket.Connect(endPoint);  //与远程主机建立连接

            //ClientSocket.Send(Encoding.ASCII.GetBytes("12345")); //测试PC -> Ubuntu的连通性

            byte[] receive = new byte[100];

            //ClientSocket.Receive(receive); //测试Ubuntu -> PC的连通性

            //Console.WriteLine(Encoding.ASCII.GetString(receive));

            while(true)
            {
                int length = ClientSocket.Receive(receive);

                Thread.Sleep(1000);//程序休眠1s, 与server端保持同步

                Console.WriteLine("接收消息为:" + Encoding.ASCII.GetString(receive));
            }
 
            ClientSocket.Close();  //关闭连接

        }
        static void Main(string[] args)//收到ubuntu虚拟机发来的数据, 并显示到终端
        {
            receive_message();
        }
    }
}

 在ubuntu端运行服务端程序.

主机(client)与ubuntu虚拟机(server)的通信(Version 1.0)

 在主机端运行客户端程序.

主机(client)与ubuntu虚拟机(server)的通信(Version 1.0)

 回到服务端.

主机(client)与ubuntu虚拟机(server)的通信(Version 1.0)