#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
/*--------------------------------------------------------------------------*/
#define MAX_MSG_SIZE 1024
char bSendBuf[1500];
char bRcvBuf[1500];
struct sockaddr_in gSvrSocketAddr;
fd_set gsReadFdSet;
/*--------------------------------------------------------------------------*/
void printMsg_WSAGetLastError()//错误处理
{
LPVOID lpMsgBuf;
int nErrorCode;
nErrorCode = WSAGetLastError();//报错处理
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
nErrorCode,
0, //Language Identifiers 0x0804, // zh-ch:0x0804,en-us:0x0409,
(LPTSTR)&lpMsgBuf,
0,
NULL
);
printf("WSAGetLastError()=%d, %s\n", nErrorCode, lpMsgBuf);
LocalFree(lpMsgBuf);
}
/*--------------------------------------------------------------------------*/
int bzygetLocalSocketAddrName(int socketFd)//获取本地socket地址
{
struct sockaddr_in SocketAddr;
int nLen;
int nRet;
memset(&SocketAddr, 0, sizeof(struct sockaddr_in));
nLen = sizeof(struct sockaddr_in);
nRet = getsockname(socketFd, (SOCKADDR*)&SocketAddr, &nLen);
if (0 == nRet)
{
printf("socketfd=%d local[ip=%d.%d.%d.%d,port=%d]\n",
socketFd,
*((BYTE*)&SocketAddr.sin_addr),
*((BYTE*)&SocketAddr.sin_addr + 1),
*((BYTE*)&SocketAddr.sin_addr + 2),
*((BYTE*)&SocketAddr.sin_addr + 3),
ntohs(SocketAddr.sin_port));
return 0;
}
else
{
printf("socketfd=%d,getsockname failure: ", socketFd);
printMsg_WSAGetLastError();
return -1;
}
}
/*--------------------------------------------------------------------------*/
int bzygetPeerSocketAddrName(int socketFd)//获取对端socket地址
{
struct sockaddr_in SocketAddr;
int nLen;
int nRet;
memset(&SocketAddr, 0, sizeof(struct sockaddr_in));
nLen = sizeof(struct sockaddr_in);
nRet = getpeername(socketFd, (SOCKADDR*)&SocketAddr, &nLen);
if (0 == nRet)
{
printf("socketfd=%d peer[ip=%d.%d.%d.%d,port=%d]\n",
socketFd,
*((BYTE*)&SocketAddr.sin_addr),
*((BYTE*)&SocketAddr.sin_addr + 1),
*((BYTE*)&SocketAddr.sin_addr + 2),
*((BYTE*)&SocketAddr.sin_addr + 3),
ntohs(SocketAddr.sin_port));
return 0;
}
else
{
printf("socketfd=%d,getpeername failure: ", socketFd);
printMsg_WSAGetLastError();
return -1;
}
}
/*--------------------------------------------------------------------------*/
int WINAPI threadIoSelect(LPVOID lpParam)//建立select并发
{
fd_set readFdSet;
int listenSocketFd;
int dataSocketFd;
int nBytesRead;
int nRetcode;
int fd;
int i;
listenSocketFd = (int)lpParam;
while (1)
{
FD_ZERO(&readFdSet);
readFdSet = gsReadFdSet;
printf("select input fdset : ");
for (i = 0; i < readFdSet.fd_count; i++)
{
fd = readFdSet.fd_array[i];
printf("%d ", fd);
}
printf("\n");
nRetcode = select(0, &readFdSet, NULL, NULL, NULL);//创建select IO复用,接收消息提升
if (0 == nRetcode)
{
continue;
}
if (0 > nRetcode)
{
printf("select failure: ");
printMsg_WSAGetLastError();
break;
}
printf("select output fdset : ");
for (i = 0; i < readFdSet.fd_count; i++)
{
fd = readFdSet.fd_array[i];
printf("%d ", fd);
}
printf("\n");
for (i = 0; i < readFdSet.fd_count; i++)
{
fd = readFdSet.fd_array[i];
if (fd == listenSocketFd)
{
//listen socket fd
dataSocketFd = accept(listenSocketFd, NULL, NULL);//non-block
if (dataSocketFd <= 0)
{
printf("socketfd=%d,accept failure: ", listenSocketFd);
printMsg_WSAGetLastError();
FD_CLR(listenSocketFd, &gsReadFdSet);
continue;
}
else
{
printf("listenSocketFd=%d accept success, new client coming socketfd=%d\n", listenSocketFd, dataSocketFd);
bzygetLocalSocketAddrName(dataSocketFd);
bzygetPeerSocketAddrName(dataSocketFd);
FD_SET(dataSocketFd, &gsReadFdSet);
}
}
else
{
//data socket fd
memset(bRcvBuf, 0, 1500);
nBytesRead = recv(fd, bRcvBuf, MAX_MSG_SIZE, 0);//进行接收
if (0 >= nBytesRead)
{
printf("socketfd=%d:data socket error,close\n", fd);
printMsg_WSAGetLastError();
FD_CLR(fd, &gsReadFdSet);
closesocket(fd);
continue;
}
else
{
bzygetLocalSocketAddrName(fd);
bzygetPeerSocketAddrName(fd);
printf("socketfd=%d, recv msglen=%d, msg=", fd, nBytesRead);
printf("%s\n", bRcvBuf);
}
}
}
}
return 0;
}
/*--------------------------------------------------------------------------*/
int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int bzyRetCode;
int bzysocketfd = -1;
int nSendDataFd;
int bzyBytesTx;
char c;
wVersionRequested = 0x0202;
bzyRetCode = WSAStartup(wVersionRequested, &wsaData);//创建网络库
if (bzyRetCode != 0)
{
printf("WSAStartup failed with error: %d\n", bzyRetCode);
return -1;
}
else
{
printf("WSAStartup sucess to startup\n");
}
if (wsaData.wVersion != wVersionRequested)
{
printf("requied wVersion=0x%04x,returned wVersion=0x%04x,returned HighestVersion=0x%04x\n",
wVersionRequested,
wsaData.wVersion,
wsaData.wHighVersion);
WSACleanup();
return -1;
}
bzysocketfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建套接字
if (bzysocketfd < 0)
{
printf("socket create failure,reason:\n");
printMsg_WSAGetLastError();
WSACleanup();
return -1;
}
else
{
printf("socket create success,socketfd=%d\n", bzysocketfd);
}
memset(&gSvrSocketAddr, 0, sizeof(struct sockaddr_in));
gSvrSocketAddr.sin_family = AF_INET;
gSvrSocketAddr.sin_port = htons(1423);
gSvrSocketAddr.sin_addr.s_addr = inet_addr("192.168.43.66");
bzyRetCode = bind(bzysocketfd, (SOCKADDR*)&gSvrSocketAddr, sizeof(SOCKADDR));//绑定
if (0 != bzyRetCode)
{
printf("socket bind failure,reason:\n");
printMsg_WSAGetLastError();
closesocket(bzysocketfd);
WSACleanup();
return -1;
}
else
{
printf("socket bind success\n");
}
bzyRetCode = listen(bzysocketfd, SOMAXCONN);
if (0 != bzyRetCode)
{
printf("socket listen failure,reason:\n");
printMsg_WSAGetLastError();
closesocket(bzysocketfd);
WSACleanup();
return -1;
}
//memset(&gsReadFdSet, 0, sizeof(fd_set));
FD_ZERO(&gsReadFdSet);//清空socketfd
FD_SET(bzysocketfd, &gsReadFdSet);//设置socketfd
CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)threadIoSelect,
(LPVOID)bzysocketfd,
0, NULL);
printf("create thread: threadIoSelect\n");
Sleep(1000);
//c = getchar();
while (1)
{
fflush(stdin);
c = getchar();
printf("please input client(socketfd) you want to send:\n");
scanf("%d", &nSendDataFd);
printf("please input msg you want to send:\n");
memset(bSendBuf, 0, 1500);
scanf("%s", bSendBuf);
bzyBytesTx = send(nSendDataFd, bSendBuf, strlen(bSendBuf), 0);//主函数作为发送
if (0 >= bzyBytesTx)
{
printf("socketfd=%d send failure,reason:\n", nSendDataFd);
printMsg_WSAGetLastError();
}
else
{
printf("socketfd=%d: send msglen=%d\n", nSendDataFd, bzyBytesTx);
}
}
WSACleanup();
return 0;
}