//Server.cpp
#include <stdio.h>
#include <winsock2.h> //winsock.h (2种套接字版本)
#pragma comment(lib,"ws2_32.lib") //wsock32.lib
#define MAXSIZE 100 //
int main()
{
//
int retVal;
char buf[MAXSIZE];
//初始化套接字库
WORD wVersionRequest;
WSADATA wsadata;
wVersionRequest=MAKEWORD(2,2);
retVal=WSAStartup(wVersionRequest,&wsadata);
if(retVal == SOCKET_ERROR)
{
printf("WSAStartup failed!");
return -1;
}
//创建套接字
SOCKET sServer;
sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sServer == INVALID_SOCKET)
{
printf("socket failed!");
WSACleanup();
return -1; //每次检测到失败后,即需要返回
}
//设置为非阻塞模式
int imode=1;
retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode);
if(retVal == SOCKET_ERROR)
{
printf("ioctlsocket failed!");
closesocket(sServer);
WSACleanup();
return -1;
}
//绑定套接字并将其设置为监听状态
SOCKADDR_IN addrServ;
addrServ.sin_family=AF_INET;
addrServ.sin_port =htons(5000);
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102");
retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //绑定套接字到某一个具体的服务器
if(retVal == SOCKET_ERROR)
{
printf("bind failed!");
closesocket(sServer);
WSACleanup();
return -1;
}
retVal=listen(sServer,1); //第二个参数,表示最大连接数目
if(retVal == SOCKET_ERROR)
{
printf("listen failed!");
closesocket(sServer);
WSACleanup();
return -1;
}
//接受连接
sockaddr_in addrClient; //定义一个临时地址,用于接受连接(注意:某个客户端由Client.cpp确定)
int len=sizeof(sockaddr_in);
SOCKET sClient;
int errcode;
while(true)
{
sClient=accept(sServer,(sockaddr *)&addrClient,&len);
if(sClient == INVALID_SOCKET)
{
errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //表示没有客户端发起连接,继续循环
{
Sleep(100);
continue;
}
else
{
printf("accept failed!");
closesocket(sServer); //连接失败,关闭服务器套接字并释放套接字库
WSACleanup(); //
return -1;
}
}
break; //
}
//接收数据
while(true)
{
retVal=recv(sClient,buf,strlen(buf),0);
if(retVal == SOCKET_ERROR)
{
errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗?
if(errcode == WSAEWOULDBLOCK) //
{
Sleep(100);
continue;
}
else
{
if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN)
{
closesocket(sClient);
closesocket(sServer);
WSACleanup();
return -1;
}
}
}
if(buf == "quit") //如果接收数据为"quit",则发送回显"quit"
{
retVal=send(sClient,buf,strlen(buf),0);
break;
}
else
{
//发送数据
while(true)
{
retVal=send(sClient,buf,strlen(buf),0); //a.回显接收数据;b.第四个参数:0?
if(retVal == SOCKET_ERROR) //错误处理
{
errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //
{
Sleep(100);
continue;
}
else
{
closesocket(sClient);
closesocket(sServer);
WSACleanup();
return -1;
}
}
break; //如果发送数据成功,则退出循环
}
}
}
}
//Client.cpp
#include <stdio.h>
#include <WinSock2.h> //winsock.h
#pragma comment(lib,"ws2_32.lib"); //wsock32.lib
#include <iostream>
using namespace std;
#include <string.h> //strcpy函数
#define MAXSIZE 100 //
int main()
{
//
int retVal;
char buf[MAXSIZE];
//初始化套接字库
WORD wVersionRequest;
WSADATA wsadata;
wVersionRequest=MAKEWORD(2,2);
retVal=WSAStartup(wVersionRequest,&wsadata);
if(retVal == SOCKET_ERROR)
{
printf("WSAStartup failed!");
return -1;
}
//创建套接字
SOCKET sClient;
sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sClient == INVALID_SOCKET)
{
printf("socket failed!");
WSACleanup();
return -1; //每次检测到失败后,即需要返回
}
//设置为非阻塞模式
int imode=1;
retVal=ioctlsocket(sClient,FIONBIO,(u_long *)&imode);
if(retVal == SOCKET_ERROR)
{
printf("ioctlsocket failed!");
closesocket(sClient);
WSACleanup();
return -1;
}
//发起连接
sockaddr_in addrServ;
addrServ.sin_family=AF_INET; //表示使用的是,TCP/IP地址家族
addrServ.sin_port =htons(5000); //为什么要使用htons宏?
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102");
int len=sizeof(sockaddr_in); //sizeof只是一个运算符,不是函数
while(true)
{
retVal=connect(sClient,(sockaddr *)&addrServ,len); //连接到某一个具体的服务器
if(retVal == INVALID_SOCKET)
{
int errcode=WSAGetLastError();
if(errcode==WSAEWOULDBLOCK || errcode==WSAEINVAL) //表示服务器端未准备好,继续循环
{
Sleep(100);
continue;
}
else
{
if(errcode == WSAEISCONN) //连接成功,则退出
{
break;
}
else //否则连接失败,关闭客户端套接字并释放套接字库
{
printf("connect failed!");
closesocket(sClient);
WSACleanup(); //
return -1;
}
}
}
}
//发送数据
while(true)
{
//
//scanf(buf);
//cin>>buf;
strcpy(buf,"Hello TCP!");
retVal=send(sClient,buf,strlen(buf),0); //a.回显接收数据;b.第四个参数:0?
if(retVal == SOCKET_ERROR) //错误处理
{
int errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //
{
Sleep(100);
continue;
}
else
{
printf("send failed!");
closesocket(sClient);
//closesocket(sServer);
WSACleanup();
return -1;
}
}
break; //如果发送数据成功,则退出循环
}
//接收数据
while(true)
{
retVal=recv(sClient,buf,strlen(buf),0);
if(retVal == SOCKET_ERROR)
{
int errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗?
if(errcode == WSAEWOULDBLOCK) //
{
Sleep(100);
continue;
}
else
{
if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN)
{
printf("recv failed!");
closesocket(sClient);
//closesocket(sServer);
WSACleanup();
return -1;
}
}
}
break;
}
}