Simple c++ server-client communication

        This blog is because I have not studied network communication in depth. I have a little understanding of it. I only know how to connect and send content. If there is any error in the content, I would like to trouble you to point it out and discuss it together.

        The server code is as follows:

#include <iostream>
#include<stdlib.h>
#include<string>
#include "winsock2.h"	//头文件
#include<WS2tcpip.h>
#pragma comment (lib,"ws2_32.lib")
using namespace std;
DWORD WINAPI threadpro(LPVOID pParam)	//线程函数
{
	SOCKET hsock = (SOCKET)pParam;	//定义一个套接字
	char buffer[1024] = { 0 };
	char sendbuffer[1024];
	if (hsock != INVALID_SOCKET)
		cout << "Start Receive" << endl;

	while (1)	//循环接受客户端发来的消息,并且以另一种方式发送给客户端
	{
		int num = recv(hsock, buffer, 1024, 0);
		if (num >= 0)
			cout << "Receive form client" << buffer << endl;
		cout << WSAGetLastError() << endl;
		if (!strcmp(buffer, "A"))
		{
			memset(sendbuffer, 0, 1024);
			strcpy_s(sendbuffer, "B");
			int ires = send(hsock, sendbuffer, sizeof(sendbuffer), 0);
			cout << "send to client" << sendbuffer << endl;
		}
		else if (!strcmp(buffer, "C"))
		{
			memset(sendbuffer, 0, 1024);
			strcpy_s(sendbuffer, "D");
			int ires = send(hsock, sendbuffer, sizeof(sendbuffer), 0);
			cout << "send to client" << sendbuffer << endl;
		}
		else if (!strcmp(buffer, "exit"))
		{
			cout << "client close" << endl;
			cout << "sever process close" << endl;
			return 0;
		}
		else
		{
			memset(sendbuffer, 0, 1024);
			strcpy_s(sendbuffer, "ERR");
			int ires = send(hsock, sendbuffer, sizeof(sendbuffer), 0);
			cout << "send to client" << sendbuffer << endl;
		}
	}
	return 0;
}

    int main()
    {
	    WSADATA wsd;
	    DWORD err = WSAStartup(MAKEWORD(2, 2), &wsd);
	    cout << err << endl;
	    SOCKET	 m_sockserver;	//套接字
	    sockaddr_in serveraddr;	//服务器地址
	    sockaddr_in serveraddrfrom;
	    SOCKET m_server[20];	//可接受最大的连接数

	    serveraddr.sin_family = AF_INET;
	    serveraddr.sin_port = htons(4600);
	    serveraddr.sin_addr.S_un.S_addr = htonl(2130706433);
	
	    m_sockserver = socket(AF_INET, SOCK_STREAM, 0);	//定义套接字

	    int i = bind(m_sockserver, (sockaddr*) & serveraddr, sizeof(serveraddr));	
                //与该地址进行绑定,成功则返回0
	    cout << "bind:" << i << endl;

	    int imaxconnect = 20;
	    int iconnect=0;
	    int ilisret;
	    char buf[] = "this is server\0";
	    char warnbuf[] = "it is over max connect\0";
	    int len = sizeof(sockaddr);
	    while (1)
	    {
		    ilisret = listen(m_sockserver, 0);	
            //进入监听模式,流式传输只可以在监听模式下才可以连接
		    m_server[iconnect] = accept(m_sockserver, (sockaddr*)&serveraddrfrom, &len);
	        //接受连接申请

		    if (m_server[iconnect] != INVALID_SOCKET)
		    {
			    int ires = send(m_server[iconnect], buf, sizeof(buf), 0);	//向其发送内容
			    cout << "accept" << ires << endl;
			    iconnect++;
			    if (iconnect > imaxconnect)
			    {
				    int ires = send(m_server[iconnect], warnbuf, sizeof(warnbuf), 0);
			    }
			    else
			    {	//启动线程
				    HANDLE m_handle;
				    DWORD nThreadId = 0;
				    m_handle = (HANDLE)::CreateThread(NULL, 0, threadpro,     (LPVOID)m_server[--iconnect], 0, &nThreadId);
			}	
		}
	}
	WSACleanup();
	return 0;
}

 The specific client code is as follows:

#include<iostream>
#include<stdlib.h>
#include"winsock2.h"
#include<time.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;

void main()
{
	WSADATA wsd;		//定义一个WSADATA对象
	WSAStartup(MAKEWORD(2,2),&wsd);		//初始化WSASDATA对象
	SOCKET m_sockclient;		//定义套接字
	sockaddr_in clientaddr;		//定义连接的地址

	clientaddr.sin_family = AF_INET;
	clientaddr.sin_port = htons(4600);
	clientaddr.sin_addr.S_un.S_addr = htonl(2130706433);
	m_sockclient = socket(AF_INET, SOCK_STREAM, 0);
	int i = connect(m_sockclient, (sockaddr*)&clientaddr, sizeof(clientaddr));	//与服务器地址连接
	cout << "connect" << i << endl;

	char buffer[1024];
	char inbuf[1024];
	int num;
	num = recv(m_sockclient, buffer, 1024, 0);	//接受服务端发来的信息
	if (num > 0)
	{
		cout << "Receive form server" << buffer << endl;
		while (1)	//循环向服务端发生消息
		{
			num = 0;
			cin >> inbuf;
			if (!strcmp(inbuf, "exit"))	//只要输入的不是exit就一直循环下去
			{
				send(m_sockclient, inbuf, sizeof(inbuf), 0);
				return ;
			}
			send(m_sockclient, inbuf, sizeof(inbuf), 0);
			num = recv(m_sockclient, buffer, 1024, 0);
			if (num >= 0)
				cout << "receive form server" << buffer << endl;
		}
	}
}

Note that there is always a helpless problem for novices here. I have written the code and it can run, but it keeps reporting errors. If you encounter such a problem, you can try to run the code on the server first, and then run the code on the client.

The result of running the above code is as follows:

1883551d08fc49e8b878f12a5ed394df.png

There are some similarities between the code writing of the server and the client:

The following figure can give you some reference: (for the code architecture of connection streaming and non-connection streaming)

39e67978395542939d395014ebd253a2.png 2d5b51e537ea4b91bfc073218affc44c.png

The general steps for encountering connectionless flow and connection flow are shown in the figure above. For details, you can look forward to the next blog. The specific application of some functions used by the server will be introduced in detail, such as send (), bind (), listen ( ), recv(), etc. The specific usage of some functions, as well as the meaning of the parameters will be written in the next blog.

        I look forward to your comments and feedback on the lack of content, and everyone will learn and make progress together! ! !

 

 

Guess you like

Origin blog.csdn.net/m0_61886762/article/details/124440744