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

       以下两个程序实现了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端运行服务端程序.

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

 回到服务端.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好梦成真Kevin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值