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);
}
}