基于WinSocket的单线程Server的实现

本文介绍了一个基于WinSocket的单线程Server实现过程,包括初始化WinSocket、创建socket、绑定地址、监听连接及收发数据等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于 WinSocket 的单线程 Server 的实现
功能描述:
程序实现一个Server监听端口的功能,运行后,其处于监听状态。当有Client连接到此Server,它停止监听,接收到自此client的数据,并将从Client收到数据反射给Client。
 
调用顺序:
1.          WSAStartup:开始对WS2_32.dll的使用。
2.          socket:创建一个socket。
3.          bind:绑定IP与Port。
4.          listen:监听一个socket。
5.          accept:接受client的连接。
6.          send:向指定socket发送数据。
7.          recv:从指定的socket接收数据。
8.          WSACleanup:关闭对WS2_32.dll的使用。
函数说明;
int WSAStartup(
 WORD wVersionRequested,
 LPWSADATA wVersionRequested,
 LPWSADATA lpWSAData
);
功能:启动WS2_32.dll,将将获得的Winsocket实现的详细信息保存到lpMSAData所指向的数据结构中,调用此函数后才可以使用Winsocket相关的函数。

     //Initialize a WSADATA object
     WSADATA wsaData;
     int nResult = WSAStartup(MAKEWORD(2,2),&wsaData);
 

 
SOCKET socket(
 int af,
 int af,
 int type,
 int protocol
);
功能:创建一个绑定到指定service provider上的socket。

     //Create a socket
     SOCKET m_socket;
     m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
 

 
int bind(
 SOCKET s,
 const struct sockaddr* s,
 const struct sockaddr* name,
 int namelen
);
功能:将本地地址与一个socket绑定。

     //Bind a socket
     sockaddr_in service;
     service.sin_family = AF_INET;
     service.sin_addr.s_addr = inet_addr("127.0.0.1");
     service.sin_port = htons(27002);
 
     if(bind(m_socket,(SOCKADDR*)&service,sizeof(service)) == SOCKET_ERROR){
         cout << "Error at bind " << endl;
         closesocket(m_socket);
         return 1;
     }

int listen(
 SOCKET s,
 int s,
 int backlog
);
功能:将一个socket置于监听状态。

     //listen on a socket
     if(listen(m_socket,20) == SOCKET_ERROR){
         cout << "Error on listen" << endl;
         return 1;
     }

SOCKET accept(
 SOCKET s,
 struct sockaddr* s,
 struct sockaddr* addr,
 int* addrlen
);
功能:接受来自外部的Client连接,返回一个新的socket。

         AcceptSocket = SOCKET_ERROR;
         while (AcceptSocket == SOCKET_ERROR) {
              AcceptSocket = accept(m_socket,NULL,NULL);
         }

 
int recv(
 SOCKET s,
 char* s,
 char* buf,
 int len,
 int len,
 int flags
);
功能:从指定的socket中接收数据。

     int nSendBytes = 0;
     int nRecvBytes = 0;
     char pRecvBytes[32] = "";
 
     nRecvBytes = recv(m_socket,pRecvBytes,32,0);
     cout << "Num of receive :" << nRecvBytes << endl;
     cout << pRecvBytes << endl;

 
int send(
 SOCKET s,
 const char* s,
 const char* buf,
 int len,
 int len,
 int flags
);
功能:向已连接的socket发送数据。

     char pSendBytes[32] = "Server:Send data";
     nSendBytes = send(m_socket,pSendBytes,32,0);

 
int WSACleanup(void);
功能:关闭能WS2_32.dll的使用,调用次数应该与WSAStartup相同。

     WSACleanup();

 
完整代码

#include <iostream>
#include "winsock2.h"
#include <windows.h>
 
using namespace std;
 
int main(){
     //启动WS2_32.dll
     WSADATA wsaData;
     int nResult = WSAStartup(MAKEWORD(2,2),&wsaData);
     if(nResult != NO_ERROR){
         cout << "Error at WSAStartup" << endl;
         return 1;
     }
 
     //创建一个socket
     SOCKET m_socket;
     m_socket = socket(AF_INET, //协议族
         SOCK_STREAM,           //SOCKET类型
         IPPROTO_TCP);          //此socket使用的协议
     if(m_socket == INVALID_SOCKET){
         cout << "Error at socket " << WSAGetLastError() << endl;
         WSACleanup();
         return 1;
     }
 
     //Bind a socket
     sockaddr_in service;
     service.sin_family = AF_INET;//协议族
     service.sin_addr.s_addr = inet_addr("127.0.0.1");//IP地址
     service.sin_port = htons(27002);               //端口号
 
     //将socket与指定的地址绑定
     if(bind(m_socket,(SOCKADDR*)&service,sizeof(service)) == SOCKET_ERROR){
         cout << "Error at bind " << endl;
         closesocket(m_socket);
         return 1;
     }
 
     //监听socket
     if(listen(m_socket,20) == SOCKET_ERROR){
         cout << "Error on listen" << endl;
          return 1;
     }
 
     //接受一个socket连接
     SOCKET AcceptSocket;
     cout << "Waiting for client to connect" << endl;
     while (1) {
         AcceptSocket = SOCKET_ERROR;
         while (AcceptSocket == SOCKET_ERROR) {
              AcceptSocket = accept(m_socket,NULL,NULL);
         }
 
         cout << "client connected!" << endl;
         m_socket = AcceptSocket;
         break;
     }
 
     int nSendBytes = 0;
     int nRecvBytes = 0;
     char pSendBytes[32] = "Server:Send data";
     char pRecvBytes[32] = "";
 
     //从socket接收数据.
     nRecvBytes = recv(m_socket,pRecvBytes,32,0);
     cout << "Num of receive :" << nRecvBytes << endl;
     cout << pRecvBytes << endl;
 
     //向socket发送数据。
     nSendBytes = send(m_socket,pSendBytes,32,0);
     if (nSendBytes == SOCKET_ERROR) {
         int nErr = WSAGetLastError();
         WSAEACCES;
         cout << nErr << endl;
     }else
        cout <<"Num of send : " << nSendBytes << endl;
     //清除WS2_32.dll
     Sleep(5000);
     WSACleanup();
   
     return 0;
}

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值