#ifdef WIN32
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netpacket/packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <ifaddrs.h>
#include <unistd.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <assert.h>
#ifdef WIN32
#pragma comment(lib,"Ws2_32.lib")
typedef SOCKET socket_t;
typedef int socklen_t;
#else
typedef int socket_t;
#define INVALID_SOCKET -1
#define closesocket close
#endif
void svr(socket_t fd)
{
struct sockaddr_in addr_;
addr_.sin_family = AF_INET;
addr_.sin_addr.s_addr = inet_addr("0.0.0.0");
addr_.sin_port = htons(12345);
int flag_=1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
(const void *)&flag_ , sizeof(int)) < 0)
{
printf("setsockopt error '%d|%s'\n",errno,strerror(errno));
return;
}
if(!!bind(fd,(const struct sockaddr*)&addr_,sizeof(addr_)))
{
printf("bind error '%d|%s'\n",errno,strerror(errno));
return;
}
listen(fd,SOMAXCONN);
struct sockaddr_in newaddr_;
socklen_t addrlen_ = sizeof(newaddr_);
const char* msg_ = "test";
do{
//int newfd_ = accept(fd,(struct sockaddr*)&newaddr_,&addrlen_);
// 使用accept4让新fd自动不可继承
int newfd_ = accept4(fd,(struct sockaddr*)&newaddr_,&addrlen_,SOCK_CLOEXEC);
if(newfd_ > 0)
{
send(newfd_,msg_,strlen(msg_)+1,0);
printf("new tcp fd '%d'\n",newfd_);
#ifdef WIN32
shutdown(newfd_,SD_BOTH);
#else
shutdown(newfd_,SHUT_RDWR);
#endif
closesocket(newfd_);
}
}while(true);
}
void cli(socket_t fd,const char* ip)
{
assert(ip);
struct sockaddr_in addr_;
addr_.sin_family = AF_INET;
addr_.sin_addr.s_addr = inet_addr(ip);
addr_.sin_port = htons(12345);
if(connect(fd,(const struct sockaddr*)&addr_,sizeof(addr_)) != 0)
{
#ifdef WIN32
printf("connect error '%d'\n",WSAGetLastError());
#else
printf("connect error '%d|%s'\n",errno,strerror(errno));
#endif
return;
}
char buf_[1024];
do{
memset(buf_,0,sizeof(buf_));
int cnt_ = recv(fd,buf_,sizeof(buf_),0);
if(cnt_ == 0)
{
printf("fd '%d'closed\n",fd);
break;
}
else if(cnt_ > 0)
{
printf("recv content '%s'\n",buf_);
}
else
{
#ifdef WIN32
printf("recv error '%d'\n",WSAGetLastError());
#else
printf("recv error '%d|%s'\n",errno,strerror(errno));
#endif
break;
}
}while(true);
}
int main(int argc,const char** argv)
{
#ifdef WIN32
WSADATA wsaData = {0};
WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif
socket_t fd_ = socket(AF_INET,SOCK_STREAM,0);
if(fd_ == INVALID_SOCKET)
{
printf("socket error '%d|%s'\n",errno,strerror(errno));
return -1;
}
if(argc > 1)
{
cli(fd_,argv[1]);
}
else
{
svr(fd_);
}
}