当前位置:C++技术网 > 资讯 > TCP-Socket客户端/服务器通信编程

TCP-Socket客户端/服务器通信编程

更新时间:2016-02-03 18:21:14浏览次数:1+次

  今天学习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;
}
  好像粘贴的代码有点多,哈哈哈,大家不要见怪,有问题的欢迎一起来讨论哈。