#include <Winsock2.h>
#include "stdio.h"
#include "stdlib.h"
#include <time.h>
#include "string.h"
#pragma comment(lib,"Ws2_32.lib")
#define MAX_CLIENT 10 //客户端数量上限
#define MAX_BUF_SIZE 65535 //缓存区大小
#define DEFAULT_PORT 5050 //端口号
#define UDP_SRV_PORT 2828
#define BUF_LENGTH 1024
struct TcpThreadParam
{
SOCKET socket; //通信套接字
sockaddr_in addr; //
};
DWORD WINAPI TcpSerThread(LPVOID lpParam);
DWORD WINAPI UdpSerThread(LPVOID lpParam);
DWORD WINAPI TcpSerRecvThread(LPVOID lpParam); //TCP接收数据线程函数
DWORD WINAPI TcpSerSendThread(LPVOID lpParam); //TCP发送数据线程函数
void main()
{
printf("Server waiting\n");
DWORD ThreadId;
HANDLE TCPThread = CreateThread(NULL, 0, TcpSerThread, NULL, 0, &ThreadId);
HANDLE UDPThread = CreateThread(NULL, 0, UdpSerThread, NULL ,0, &ThreadId);
WaitForSingleObject(TCPThread,INFINITE);
WaitForSingleObject(UDPThread,INFINITE);
CloseHandle(TCPThread);
CloseHandle(UDPThread);
}
//-----------------tcp-------------------------------//
DWORD WINAPI TcpSerThread(LPVOID lpParam)
{
WSADATA wsaData;
SOCKET sListen,sAccept; //服务器监听套接字,连接套接字
int serverport=DEFAULT_PORT; //服务器端口号
struct sockaddr_in ser,cli; //服务器地址,客户端地址
int iLen;
//-----------------初始话环境-------------------------------//
if (WSAStartup(MAKEWORD(2,2),&wsaData) !=0)
{
printf("加载sock失败\n");
return 0;
}
//---------------创建监听套接字-----------------------------//
sListen =socket(AF_INET,SOCK_STREAM,0);
if (sListen == INVALID_SOCKET)
{
printf("socket() Failed:%d\n",WSAGetLastError());
return 0;
}
//----------创建服务器地址:包含IP+端口号-------------------//
ser.sin_family=AF_INET;
ser.sin_port=htons(serverport); //服务器端口号
ser.sin_addr.s_addr=htonl(INADDR_ANY); //服务器IP地址,默认使用本机IP
//-------------绑定tcp套接字和服务器地址---------------------//
if (bind(sListen,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR)
{
printf("绑定失败:%d\n",WSAGetLastError());
return 0;
}
//-----------------通过监听套接字进行监听-------------------//
if (listen(sListen,5)==SOCKET_ERROR)
{
printf("监听失败:%d\n",WSAGetLastError());
return 0;
}
//----------------接收客户端连接并创建线程-------------------//
while (1)
{
iLen=sizeof(cli);
sAccept=accept(sListen,(struct sockaddr*)&cli,&iLen);//接收连接
if (sAccept==INVALID_SOCKET)
{
printf("accept() Failed:%d\n",WSAGetLastError());
break;
}
//---------传入线程处理函数的参数,创建线程服务-----------//
TcpThreadParam Param; //传入线程处理函数的参数
Param.socket = sAccept;//与客户连接的套接字号
Param.addr = ser;//客户端地址结构
DWORD dwThreadId;
CreateThread(NULL, 0, TcpSerSendThread, &Param, 0, &dwThreadId);
//创建接收线程
CreateThread(NULL, 0, TcpSerRecvThread, &Param, 0, &dwThreadId);
}
//----------程序执行完后释放资源-------------------------//
closesocket(sListen);
WSACleanup();
return 0;
}
//--------------TCP接收数据线程函数------------------------//
DWORD WINAPI TcpSerRecvThread(LPVOID lpParam)
{
char recv_buf[BUF_LENGTH];//接收缓存
int iRecv;
//获取线程参数
SOCKET sAccept = ((TcpThreadParam*)lpParam)->socket;
SOCKADDR_IN SerAddr = ((TcpThreadParam*)lpParam)->addr;
while(1)
{
iRecv=recv(sAccept,recv_buf,sizeof(recv_buf),0);
if (iRecv ==SOCKET_ERROR) //接收错误
{
printf("recv() Failed:%d\n",WSAGetLastError());
break;
}
else if (!strcmp(recv_buf,"end"))
{
break;
}
else
{
printf("client say:");
printf("%s\n",recv_buf);
}
}
//断开该连接
printf("close the session!\n");
closesocket(sAccept);
return 0;
}
//-----------------------TCP发送数据线程函数------------//
DWORD WINAPI TcpSerSendThread(LPVOID lpParam)
{
char send_buf[BUF_LENGTH]; //发送缓存
int iSend;
SOCKET sAccept = ((TcpThreadParam*)lpParam)->socket;
SOCKADDR_IN SerAddr = ((TcpThreadParam*)lpParam)->addr;
while (1)
{
printf("server say:\n");
memset(send_buf,0,sizeof(send_buf)); //缓存清0
scanf("%s",send_buf);
iSend=send(sAccept,send_buf,sizeof(send_buf),0); //通过套接字发送数据给服务器
if (iSend==SOCKET_ERROR) //发送不成功
{
printf("send() Failed:%d\n",WSAGetLastError());
break;
}
else if (!strcmp(send_buf,"end")) //输入end,结束
{
break;
}
else ; //发送成功
}
printf("close the client!\n");
closesocket(sAccept);
return 0;
}
//--------------udp线程函数------------------------//
DWORD WINAPI UdpSerThread(LPVOID lpParam)//UDP接收数据线程函数
{
WSADATA wsaData;
int iport=UDP_SRV_PORT; //服务器进程端口号
SOCKET sSocket; //服务器套接字
SOCKET sServe;
struct sockaddr_in ser,cli; //服务器地址,客户端地址
int iLen;
char send_buf[BUF_LENGTH]; //发送缓存
char recv_buf[BUF_LENGTH]; //接收缓存
int iSend,iRecv; //接收数据和发送数据长度
time_t rawtime;//time_t是long型
struct tm *timeinfo;//时间的结构体
//---------------------加载协议栈----------------------//
if (WSAStartup(MAKEWORD(2,2),&wsaData) !=0)
{
printf("Failed to load Winsock.\n");
return 0;
}
//-------------------创建服务器数据报套接字---------//
sSocket =socket(AF_INET,SOCK_DGRAM,0);
if (sSocket == INVALID_SOCKET)
{
printf("socket() Failed:%d\n",WSAGetLastError());
return 0;
}
//创建服务器地址:包含IP+端口号
ser.sin_family=AF_INET;
ser.sin_port=htons(UDP_SRV_PORT); //服务器端口号
ser.sin_addr.s_addr=htonl(INADDR_ANY); //服务器IP地址,以本机IP地址作为服务器地址
//绑定服务套接字和服务器地址
if (bind(sSocket,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR)
{
printf("blind() Failed:%d\n",WSAGetLastError());
return 0;
}
while (1)
{
//接收客户端发来的数据
memset(recv_buf,0,sizeof(recv_buf)); //缓存清0
iLen=sizeof(cli);
iRecv=recvfrom(sSocket,recv_buf,sizeof(recv_buf),0,(SOCKADDR*)&cli,&iLen);
if (iRecv ==SOCKET_ERROR) //接收错误
{
printf("recv() Failed:%d\n",WSAGetLastError());
return 0;
}
else printf("获取命令:%s\n",recv_buf); //接收成功,打印输出
if(strcmp(recv_buf,"time")==0)//处理接收的数据
{
rawtime=time(NULL);//获取当地时间
rawtime=rawtime+3600;
timeinfo = localtime(&rawtime);//将时间转换成结构体格式时间
printf("服务器时间:%s",asctime(timeinfo));//asctime 标准的ASCII时间格式
itoa(rawtime,send_buf,10);
}
else
{
printf("没有这条指令!\n");
}
//发送数据给客户端
iSend=sendto(sSocket,send_buf,sizeof(send_buf),0,(SOCKADDR*)&cli,sizeof(cli));
if (iSend==SOCKET_ERROR) //发送错误
{
printf("send() Failed:%d\n",WSAGetLastError());
break;
}
else printf("send success!\n"); //发送成功
}
closesocket(sSocket);
WSACleanup();
return 0;
}