C# winform实现与linux socket通信

104 篇文章 5 订阅
17 篇文章 1 订阅

windows 主机下winform Form1.cs代码:

//Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Threading;
using System.Net.Sockets;

using System.IO; 

namespace storage_app
{
    public partial class Form1 : Form
    {
        public Socket newclient;
        public bool Connected;
        public Thread myThread;
        public delegate void MyInvoke(string str); 

        public Form1()
        {

            InitializeComponent();
            StartPosition = FormStartPosition.CenterScreen;
            //关闭对文本框的非法线程操作检查
            TextBox.CheckForIllegalCrossThreadCalls = false;
        }
        //Thread threadclient = null;
        Socket socketclient = null;
        List<IPEndPoint> mlist = new List<IPEndPoint>();  

        private void conn_btn_Click(object sender, EventArgs e)
        {
            this.conn_btn.Enabled = false;
            socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            string ipadd = "192.168.66.666";
            int port = 8866;
            IPEndPoint ie = new IPEndPoint(IPAddress.Parse(ipadd), port);
            try
            {
                //客户端套接字连接到网络节点上,用的是Connect
                socketclient.Connect(ie);
                string sendStr = "hello!This is a socket test";
                byte[] bs = Encoding.ASCII.GetBytes(sendStr);
                socketclient.Send(bs, bs.Length, 0);//发送测试信息
                string recvStr = "";
                byte[] recvBytes = new byte[1024];
                int bytes;
                bytes = socketclient.Receive(recvBytes, recvBytes.Length, 0);//从服务器端接受返回信息
                recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);
                MessageBox.Show("连接成功!\r\n");

            }
            catch (Exception cone)
            {
                //MessageBox.
                MessageBox.Show("连接失败\r\n"+cone.ToString());
                this.conn_btn.Enabled = true;
                return;
            }


            //threadclient.IsBackground = true;

            //threadclient.Start();

        }


        //获取当前系统时间
        private DateTime GetCurrentTime()
        {
            DateTime currentTime = new DateTime();
            currentTime = DateTime.Now;
            return currentTime;
        }

    }
}

linux 服务端代码:

//server.cpp
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<sys/epoll.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<errno.h>
#include<unistd.h>
#include<string.h>
#include<netinet/tcp.h>
#define SERVER_PORT 8866
#define LENGTH_OF_LISTEN_QUEUE 20
#define MAXBUF 100

using namespace std;
int EstablishServer(struct sockaddr_in *addr,socklen_t addrLen,int port);
void *HeartService(void *arg);
void setnonblocking(int sock);

int main()
{
    struct sockaddr_in server_addr,client_addr;
    int serverFd,clientFd;
    socklen_t clientLen=sizeof(struct sockaddr);
    //建立socket连接
    serverFd=EstablishServer(&server_addr,sizeof(server_addr),SERVER_PORT);
    if(serverFd==-1)
    {
        cout<<"serverFd create failed!"<<endl;
        exit(1);
    }
    for(;;)
    {
        //等待连接的请求
        if((clientFd=accept(serverFd,(struct sockaddr*)&client_addr,&clientLen))<0)
        {
            perror("accept wrong !:");
            exit(1);
        }
        cout<<"----------------------------------------------------------------"<<endl;
        printf("accept from %s:%d\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);
        pthread_t clientTid;
        int pthrst=pthread_create(&clientTid,NULL,HeartService,(void*)&clientFd);
        if(pthrst!=0)
        {
            perror("pthread_create wrong ! :");
        }       
    }
    return 0;
}
//建立服务端socket的通信,绑定端口
int EstablishServer(struct sockaddr_in *addr,socklen_t addrLen,int port)
{
    int listenfd=socket(AF_INET,SOCK_STREAM,0);
    if(listenfd<0)
    {
        perror("listenfd socket error");
        return -1;
    }
    bzero(addr,addrLen);
    addr->sin_family=AF_INET;
    addr->sin_addr.s_addr=htonl(INADDR_ANY);
    addr->sin_port=htons(port);
    if(bind(listenfd,(struct sockaddr*)addr,addrLen)<0)
    {
        perror("bind error");
        return -1;
    }
    if(listen(listenfd,LENGTH_OF_LISTEN_QUEUE)<0)
    {
        perror("listen error");
        return -1;
    }
    return listenfd;
}
//心跳机制线程
void *HeartService(void *arg)
{
    //获得自身的线程号
    pthread_t tid=pthread_self();
    //获得传送过来的clientFd
    int clientFd=*(int *)arg;
    cout<<"New thread create,the tid is "<<tid<<" the clientFd is "<<clientFd<<endl;
    int sockfd;//用于获取epoll函数的fd值
    char buf[MAXBUF];
    int epfd,nfds,n,m,count=0;
    struct epoll_event ev,events[20];//声明epoll_event结构体的变量,ev用于注册事件,events数组用于回传要处理的事件
    int keepAlive=1;//开启keepalive属性
    int keepIdle=5;//如该连接在5秒内没有任何数据往来,则进行探测
    int keepInterval=2;//探测时发包的时间间隔为2秒
    int keepCount=3;//探测尝试的次数。如果第1次探测包就收到响应了,则后2次的不再发送
    setsockopt(clientFd,SOL_SOCKET,SO_KEEPALIVE,(void *)&keepAlive,sizeof(keepAlive));
    setsockopt(clientFd,SOL_TCP,TCP_KEEPIDLE,(void *)&keepIdle,sizeof(keepIdle));
    setsockopt(clientFd,SOL_TCP,TCP_KEEPINTVL,(void *)&keepInterval,sizeof(keepInterval));
    setsockopt(clientFd,SOL_TCP,TCP_KEEPCNT,(void *)&keepCount,sizeof(keepCount));
    //把客户端的socket设置为非阻塞方式
    setnonblocking(clientFd);
    epfd=epoll_create(256);//生成epoll专用的文件描述符,指定生成描述符的最大范围为256
    ev.data.fd=clientFd;
    ev.events=EPOLLIN|EPOLLET;
    epoll_ctl(epfd,EPOLL_CTL_ADD,clientFd,&ev);
    for(;;)
    {
        nfds=epoll_wait(epfd,events,20,-1);
        cout<<"the tid is "<<tid<<" the clientFd is "<<clientFd<<" the count is "<<++count<<endl;
        for(int i=0;i<nfds;++i)
        {
            if(events[i].events&EPOLLIN)
            {
                if((sockfd=events[i].data.fd)<0)
                {
                    cout<<"It is recevied continue!"<<endl;
                    continue;//因为下面设置了,所以这里考虑了
                }
                if((n=recv(sockfd,buf,MAXBUF,0))<0)
                {
                    if(errno==ECONNRESET)//表示连接被重置了,已经无效了,关闭它,删除它
                    {
                        printf("It is ECONNRESET:%s\n",strerror(ECONNRESET));
                        epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);//可以把这个sockfd从epfd队列中删除了

                    }
                    else if(errno==ETIMEDOUT)
                    {
                        cout<<"Ha Ha you want ETIMEDOUT"<<endl;

                    }
                    else
                        cout<<"read error!"<<endl;  //其他错误
                    epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);
                    return 0;
                }
                else if(n==0)//有读事件触发,但是read返回0,所以是对面已经关闭sockfd了
                {
                    cout<<"n=0 ,sockfd is "<<sockfd<<" and tid is "<<tid<<endl;
                    epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL);
                    close(sockfd);
                }
                else
                {
                    buf[n]='\0';
                    cout<<"received:"<<buf<<" and sockfd is "<<sockfd<<endl;
                    ev.data.fd=sockfd;
                    ev.events=EPOLLOUT|EPOLLET;
                    epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
                }
            }
            else if(events[i].events&EPOLLOUT)
            {
                sockfd=events[i].data.fd;
                m=strlen(buf);
                cout<<"m is "<<m<<endl;
                if(write(sockfd,buf,m)<0)
                {
                    cout<<"write wrong ! and sockfd is:"<<sockfd<<endl;
                }
                else
                {
                    cout<<"send success and buf is "<<buf<<endl;
                }

                ev.data.fd=sockfd;
                ev.events=EPOLLIN|EPOLLET;
                epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//修改sockfd上要处理的事件为EPOLLIN,下次监听读事件 
            }
        }
    }  
}
void setnonblocking(int sock)
{
    int opts;
    opts=fcntl(sock,F_GETFL);//把sock的属性查询出来,存到opts中
    if(opts<0)
    {
        perror("fcntl(sock,GETFL)");
        exit(1);
    }
    opts=opts|O_NONBLOCK;//把opts中的某一位O_NONBLOCK置为生效
    if(fcntl(sock,F_SETFL,opts)<0)
    {
        perror("fcntl(sock,SETFL,opts)");
        exit(1);
    }
}

参考:http://blog.csdn.net/liujiakunit/article/details/9772283

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值