今天学习Socket编程,于是自己动手写了一遍客户端和服务器的代码。
客户端代码:
#include <WinSock2.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main()
{
WORD Version;
Version = MAKEWORD(1, 1);
WSADATA data;
int nError = WSAStartup(Version, &data);
if(nError != 0)
{
int error = WSAGetLastError();
cout << error << endl;
cout << "初始化版本库失败" << endl;
return 1;
}
if(HIBYTE(data.wVersion) != 1 || LOBYTE(data.wVersion) != 1)
{
WSACleanup();
cout << "套接字库版本不是1.1" << endl;
return 1;
}
SOCKET mySocket = socket(AF_INET, SOCK_STREAM, 0);
if(mySocket == INVALID_SOCKET)
{
WSACleanup();
cout << "初始化套接字失败" << endl;
return 1;
}
SOCKADDR_IN addrSock;
addrSock.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addrSock.sin_family = AF_INET;
addrSock.sin_port = htons(6000);
int nLen = sizeof(SOCKADDR);
if(connect(mySocket, (SOCKADDR*)&addrSock, nLen))
{
closesocket(mySocket);
WSACleanup();
cout << "连接失败" << endl;
return 1;
}
while(true)
{
//发送数据
char SendBuf[100] = {0};
cin.getline(SendBuf, 100);
if(strcmp(SendBuf, "exit") == 0) break;
if(SOCKET_ERROR == send(mySocket, SendBuf, strlen(SendBuf) + 1, 0))
{
closesocket(mySocket);
WSACleanup();
cout << "发送数据失败" << endl;
return 1;
}
//接收数据
char RecvBuf[100] = {0};
if(SOCKET_ERROR == recv(mySocket, RecvBuf, 100, 0))
{
closesocket(mySocket);
WSACleanup();
cout << "接收数据失败" << endl;
return 1;
}
char strTmp[200] = {0};
sprintf_s(strTmp, "%s say %s", inet_ntoa(addrSock.sin_addr), RecvBuf);
cout << strTmp << endl;
}
closesocket(mySocket);
WSACleanup();
return 0;
}
服务器代码:
#include <WinSock2.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main()
{
WORD Version;
Version = MAKEWORD(1, 1);
WSADATA data;
int nError = WSAStartup(Version, &data);
if(nError != 0)
{
int error = WSAGetLastError();
cout << error << endl;
cout << "初始化版本库失败" << endl;
return 1;
}
if(HIBYTE(data.wVersion) != 1 || LOBYTE(data.wVersion) != 1)
{
WSACleanup();
cout << "套接字库版本不是1.1" << endl;
return 1;
}
SOCKET mySocket = socket(AF_INET, SOCK_STREAM, 0);
if(mySocket == INVALID_SOCKET)
{
WSACleanup();
cout << "初始化套接字失败" << endl;
return 1;
}
SOCKADDR_IN addrSock;
addrSock.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSock.sin_family = AF_INET;
addrSock.sin_port = htons(6000);
int nLen = sizeof(SOCKADDR);
if(bind(mySocket, (SOCKADDR*)&addrSock, nLen))
{
closesocket(mySocket);
WSACleanup();
cout << "绑定失败" << endl;
return 1;
}
if(listen(mySocket, 5))
{
closesocket(mySocket);
WSACleanup();
cout << "监听失败" << endl;
return 1;
}
SOCKET AccSocket;
cout << "服务器运行中" << endl;
while(true)
{
SOCKADDR_IN accSockAddr;
int nAccLen = sizeof(SOCKADDR);
AccSocket = accept(mySocket, (SOCKADDR*)&accSockAddr, &nAccLen);
if(AccSocket == INVALID_SOCKET)
{
closesocket(mySocket);
WSACleanup();
cout << "接收请求失败" << endl;
return 1;
}
//接收数据
char RecvBuf[100] = {0};
if(SOCKET_ERROR == recv(AccSocket, RecvBuf, 100, 0))
{
cout << "接收数据失败" << endl;
break;
}
if(strlen(RecvBuf) != 0)
{
char strTmp[200] = {0};
sprintf_s(strTmp, "%s say %s", inet_ntoa(accSockAddr.sin_addr), RecvBuf);
cout << strTmp << endl;
}
//发送数据
char SendBuf[100] = "Hello, I'm Server";
if(SOCKET_ERROR == send(AccSocket, SendBuf, strlen(SendBuf) + 1, 0))
{
cout << "发送数据失败" << endl;
break;
}
}
closesocket(AccSocket);
closesocket(mySocket);
WSACleanup();
return 0;
}
发现服务器接收了一次客户端发送的信息后就不再接收了,于是就去再看一遍socket的知识,没发现问题所在,于是就去百度,原来是accept的位置不对,如果是上面那样,会导致接收一次信息后,再去accept,客户端如果想发送信息就要再一次connect,所以才导致了服务器接收了一次信息后就不再接收了。
服务器修改代码如下:
#include <WinSock2.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main()
{
WORD Version;
Version = MAKEWORD(1, 1);
WSADATA data;
int nError = WSAStartup(Version, &data);
if(nError != 0)
{
int error = WSAGetLastError();
cout << error << endl;
cout << "初始化版本库失败" << endl;
return 1;
}
if(HIBYTE(data.wVersion) != 1 || LOBYTE(data.wVersion) != 1)
{
WSACleanup();
cout << "套接字库版本不是1.1" << endl;
return 1;
}
SOCKET mySocket = socket(AF_INET, SOCK_STREAM, 0);
if(mySocket == INVALID_SOCKET)
{
WSACleanup();
cout << "初始化套接字失败" << endl;
return 1;
}
SOCKADDR_IN addrSock;
addrSock.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSock.sin_family = AF_INET;
addrSock.sin_port = htons(6000);
int nLen = sizeof(SOCKADDR);
if(bind(mySocket, (SOCKADDR*)&addrSock, nLen))
{
closesocket(mySocket);
WSACleanup();
cout << "绑定失败" << endl;
return 1;
}
if(listen(mySocket, 5))
{
closesocket(mySocket);
WSACleanup();
cout << "监听失败" << endl;
return 1;
}
SOCKET AccSocket;
cout << "服务器运行中" << endl;
SOCKADDR_IN accSockAddr;
int nAccLen = sizeof(SOCKADDR);
AccSocket = accept(mySocket, (SOCKADDR*)&accSockAddr, &nAccLen);
if(AccSocket == INVALID_SOCKET)
{
closesocket(mySocket);
WSACleanup();
cout << "接收请求失败" << endl;
return 1;
}
cout << "有客户端连接" << endl;
while(true)
{
//接收数据
char RecvBuf[100] = {0};
if(SOCKET_ERROR == recv(AccSocket, RecvBuf, 100, 0))
{
//cout << "接收数据失败" << endl;
cout << "客户端断开" << endl;
AccSocket = accept(mySocket, (SOCKADDR*)&accSockAddr, &nAccLen);
if(AccSocket == INVALID_SOCKET)
{
closesocket(mySocket);
WSACleanup();
cout << "接收请求失败" << endl;
return 1;
}
cout << "有客户端连接" << endl;
continue;
}
if(strlen(RecvBuf) != 0)
{
char strTmp[200] = {0};
sprintf_s(strTmp, "%s say %s", inet_ntoa(accSockAddr.sin_addr), RecvBuf);
cout << strTmp << endl;
}
//发送数据
char SendBuf[100] = "Hello, I'm Server";
if(SOCKET_ERROR == send(AccSocket, SendBuf, strlen(SendBuf) + 1, 0))
{
cout << "发送数据失败" << endl;
break;
}
}
closesocket(AccSocket);
closesocket(mySocket);
WSACleanup();
return 0;
}
好像粘贴的代码有点多,哈哈哈,大家不要见怪,有问题的欢迎一起来讨论哈。