基于Select模型通信程序的编写,编译和执行

任务目标

编写Win32程序模拟实现基于Select模型的两台计算机之间的通信,要求编程实现服务器端与客户端之间双向数据传递。客户端向服务器端发送“计算从1到100的奇数和”,服务器回应客户端并给出从1到100的奇数和结果。

核心代码

Server:
1.	#include "InitSock.h"
2.	#include <stdio.h>
3.	#include <string.h>
4.	#include <stdlib.h>
5.	CInitSock initSock;
6.	int main(int argc, char* argv[])
7.	{
8.	    //创建套接字
9.	    SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
10.	    if(sListen == INVALID_SOCKET)
11.	    {
12.	        printf("socket error !");
13.	        return 0;
14.	    }
15.	
16.	    //绑定IP和端口
17.	    sockaddr_in sin;
18.	    sin.sin_family = AF_INET;
19.	    sin.sin_port = htons(5555);
20.	    sin.sin_addr.S_un.S_addr = INADDR_ANY; 
21.	    if(bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
22.	    {
23.	        printf("bind error !");
24.	    }
25.	    ::listen(sListen, 5);
26.	
27.	    int itotal=0;
28.	    int ii;
29.	    for(ii=1;ii<=100;ii++)
30.	    {
31.	        if(ii % 2 ==1)
32.	        {
33.	            itotal+=ii;
34.	        }
35.	    }
36.	    
37.	    fd_set fdSocket;
38.	    FD_ZERO(&fdSocket);
39.	    FD_SET(sListen, &fdSocket);
40.	    while(true) {
41.	        fd_set fdRead = fdSocket;
42.	        int nRet = ::select(0, &fdRead, NULL, NULL, NULL);
43.	        if(nRet > 0) {
44.	            for(int i=0; i<(int)fdSocket.fd_count; i++) {
45.	                if(FD_ISSET(fdSocket.fd_array[i], &fdRead)) {
46.	                    if(fdSocket.fd_array[i] == sListen) {
47.	                        if(fdSocket.fd_count < FD_SETSIZE) {
48.	                            sockaddr_in addrRemote;
49.	                            int nAddrLen = sizeof(addrRemote);
50.	                            SOCKET sNew = ::accept(sListen, (SOCKADDR*)&addrRemote, &nAddrLen);
51.	                            FD_SET(sNew, &fdSocket);
52.	                            printf("接收到连接(%s)
", ::inet_ntoa(addrRemote.sin_addr));
53.	                        }
54.	                        else {
55.	                            printf("连接数量过多!
");
56.	                            continue;
57.	                        }
58.	                    }
59.	                    else {
60.	                        //接收数据
61.	                        char szText[256];
62.	                        int nRecv = ::recv(fdSocket.fd_array[i], szText, strlen(szText), 0);
63.	                        if(nRecv > 0) {
64.	                            szText[nRecv] = '';
65.	                            printf("接收到数据:%s
", szText);
66.	
67.	                            //发送数据
68.	    
69.	                        char str[10];
70.	                        char str1[20]="1到100的奇数和为:";
71.	                        itoa(itotal,str,10);
72.	                        char * sendData = strcat(str1,str);
73.	                        ::send(fdSocket.fd_array[i], sendData, strlen(sendData), 0);
74.	                    
75.	
76.	                        }
77.	                        else {
78.	                            ::closesocket(fdSocket.fd_array[i]);
79.	                            FD_CLR(fdSocket.fd_array[i], &fdSocket);
80.	                        }
81.	                    }
82.	                }
83.	            }
84.	    
85.	    
86.	        }
87.	        else {
88.	            printf("选择失败!
");
89.	            break;
90.	        }
91.	    }
92.	    return 0;
93.	}
94.	
95.	

Client:
1.	#include "winsock2.h"
2.	#include <iostream>
3.	#pragma comment(lib, "ws2_32.lib")
4.	using namespace std;
5.	BOOL RecvLine(SOCKET s, char* buf); //读取一行数据
6.	int main(int argc, char* argv[])
7.	{
8.	    const int BUF_SIZE = 64;
9.	    WSADATA wsd; //WSADATA变量
10.	    SOCKET sHost; //服务器套接字
11.	    SOCKADDR_IN servAddr; //服务器地址
12.	    char buf[BUF_SIZE]; //接收数据缓冲区
13.	    char bufRecv[BUF_SIZE];
14.	    int retVal; //返回值
15.	    //WSAStartup()初始化套结字动态库
16.	    if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
17.	    {
18.	        cout << "WSAStartup failed!" << endl;
19.	        return -1;
20.	    }
21.	    //socket()创建套接字
22.	    sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
23.	    if(INVALID_SOCKET == sHost)
24.	    {
25.	        cout << "socket failed!" << endl;
26.	        WSACleanup();//释放套接字资源
27.	        return  -1;
28.	    }
29.	    //设置服务器地址
30.	    servAddr.sin_family =AF_INET;
31.	    servAddr.sin_addr.s_addr = inet_addr("172.21.0.140");   servAddr.sin_port = htons((short)5555);
32.	    int nServAddlen  = sizeof(servAddr);
33.	    //connet()连接服务器
34.	    retVal=connect(sHost,(LPSOCKADDR)&servAddr, sizeof(servAddr));
35.	    if(SOCKET_ERROR == retVal)
36.	    {
37.	        cout << "connect failed!" << endl;
38.	        closesocket(sHost); //关闭套接字
39.	        WSACleanup(); //释放套接字资源
40.	        return -1;
41.	    }
42.	    int FLAG = 1;
43.	    //while(true)
44.	    while(FLAG)
45.	    {
46.	        //send()向服务器发送数据
47.	        ZeroMemory(buf, BUF_SIZE);
48.	        char sendM[] = "计算从1到100的奇数和";
49.	        retVal = send(sHost, sendM, strlen(sendM), 0);
50.	        if (SOCKET_ERROR == retVal)
51.	        {
52.	            cout << "send failed!" << endl;
53.	            closesocket(sHost); //关闭套接字
54.	            WSACleanup(); //释放套接字资源
55.	            return -1;
56.	        }
57.	        //Recv()接收服务器端的数据
58.	        ZeroMemory(bufRecv, BUF_SIZE);
59.	        recv(sHost, bufRecv,BUF_SIZE , 0); // 接收服务器端的数据,只接收5个字符cout << endl <<"从服务器接收数据:"<<endl<< bufRecv;
60.	        cout << endl <<"从服务器接收数据:"<<endl<< bufRecv;
61.	        cout<<endl;
62.	        FLAG=0;
63.	    }
64.	    closesocket(sHost); //关闭套接字
65.	    WSACleanup(); //释放套接字资源
66.	    return 0;
67.	}
68.	

原文地址:https://www.cnblogs.com/boxker/p/10745487.html