c++ winsocket(二)

一 问题:

1  客户端调用两次send函数,服务器只会接受一次,服务器就会断开本次连接。

    解决方法在服务器端的 recv方法一个死循环.

二代码

1 mysocket.h

const size_t IP_BUF_SIZE = 65;
class MySocket{
public:
 SOCKET	m_socket;
 SOCKET	m_con;
public:
	void init();
	void mybind();
	void mylisten();
	SOCKET myaccept(); 
	void mysend(SOCKET socket,char * ch);
	void myrecv(SOCKET socket);
	void myclose();

	void myconnect();
};

2 mysocket.cpp

#include <Winsock2.h>
#include <ws2tcpip.h>
#include <iostream>
#include "mysocket.h"
#pragma comment(lib, "ws2_32.lib") //socket编程需要引用该库

 void MySocket::init(){
  WSADATA wsa_data; //WSADATA变量,包含windows socket执行的信息
  int sys_fun_result = 0; 
	// 初始化winsock动态库(ws2_32.dll),MAKEWORD(2, 2)用于请求使用winsock2.2版本

sys_fun_result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
if (sys_fun_result != 0) {
       std::cout << "WSAStartup() function failed: " << sys_fun_result << "\n";
       system("pause");
        return ;
    }

 m_socket=socket(PF_INET,SOCK_STREAM,0);//创建套接字
 std::cout<<"Winsock初始化成功"<<std::endl;
}

 void MySocket::mybind(){
	int sys_fun_result = 0;
	SOCKADDR_IN addr;
    addr.sin_family=AF_INET;
    //addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//ip地址
	addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    addr.sin_port=htons(16001);//绑定端口
	bind(m_socket,(SOCKADDR*)&addr,sizeof(SOCKADDR));//绑定
	if (sys_fun_result == SOCKET_ERROR) {
         std::cout << "bind() function failed with error: " << WSAGetLastError() << "\n";
         closesocket(m_socket);
          WSACleanup();
          return ;
      }
 }
 void MySocket::mylisten(){
	 int sys_fun_result = 0;
    sys_fun_result = listen(m_socket, SOMAXCONN);//  SOMAXCONN 默认值 5  代表能够接收的最多的连接
   if (sys_fun_result == SOCKET_ERROR) {
          std::cout << "listen() function failed with error: " << WSAGetLastError() << "\n";
          closesocket(m_socket);
          return ;
     }
 }

 SOCKET MySocket::myaccept(){
char ip_buf[IP_BUF_SIZE];
SecureZeroMemory(ip_buf, IP_BUF_SIZE);
 SOCKADDR_IN clientsocket;
    int len=sizeof(SOCKADDR);
	m_con=accept(m_socket,(SOCKADDR*)&clientsocket,&len);
	 if (m_con == INVALID_SOCKET) {
         std::cout << "accept() function failed with error: " << WSAGetLastError() << "\n";
         closesocket(m_socket);
          WSACleanup();
          system("pause");
         return NULL;
     }
	 //ip地址转换
      inet_ntop(AF_INET, &clientsocket, ip_buf, IP_BUF_SIZE);
     std::cout << "client ip address: " << ip_buf << std::endl;
	 return m_con;
 }
 void MySocket::mysend(SOCKET socket , char * ch){
	 int sys_fun_result = 0;
	 char * sendBuf = ch;
	// memset(sendBuf,0,sizeof(sendBuf));
;
     sys_fun_result= send(socket,sendBuf,100,0);
	 if(sys_fun_result==SOCKET_ERROR){
	   std::cout << "mysend() function failed with error: " << WSAGetLastError() << "\n";
	 }
	 std::cout<<sys_fun_result<<std::endl;
	 std::cout<<strlen(sendBuf)<<std::endl;
	 std::cout<<sizeof(sendBuf)<<std::endl;
	  std::cout<<sendBuf;
 }
 void MySocket::myrecv(SOCKET socket){
	 char receiveBuf[100];
	  int sys_fun_result = 0;
	while(1){
	 memset(receiveBuf,0,sizeof(receiveBuf));
	 /*         当recv返回值小于0时,socket报错;
                当recv返回值大于0时,成功,返回值为接收到的数据长度;
                当recv返回值等于0时,表示此时connect已经关闭,没有接收到数据。*/
	 
     sys_fun_result=recv(socket,receiveBuf,sizeof(receiveBuf),0);//这里不能用 strlen(receiveBuf) 因为 strlen(receiveBuf)=0

	 if (sys_fun_result == SOCKET_ERROR)
		{
			std::cout<<"error with code = "<<WSAGetLastError()<<std::endl;
			exit(1);
		}
	   printf("receiveBuf=%s\n",receiveBuf);
	}
 }
 void MySocket::myclose(){
      closesocket(m_con);//关闭
        WSACleanup();//释放资源的操作
 }
 void MySocket::myconnect(){
	 int sys_fun_result = 0;
    SOCKADDR_IN clientsock_in;
    clientsock_in.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    clientsock_in.sin_family=AF_INET;
    clientsock_in.sin_port=htons(16001);
	sys_fun_result = connect(m_socket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR));

	if (sys_fun_result == SOCKET_ERROR) {
          std::cout << "connect() function failed with error: " << WSAGetLastError() << "\n";
          WSACleanup();
          system("pause");
          return ;
      }
 }

3  client.cpp

#include <windows.h>
#include <iostream>
#include "mysocket.h"
void main(){
	    char message[100];
	MySocket * mysocket= new MySocket();
	mysocket->init();
	mysocket->myconnect();
	
		//std::cout<<"请输入"<<std::endl;
	while(1){
		printf("请输入");
	    scanf("%s",message);
		printf("已输入:%s",message);
		mysocket->mysend(mysocket->m_socket,message);
	    Sleep(5000);//每5秒
	}
	
	system("pause");
	
}

4  server.cpp

#include <windows.h>
#include "mysocket.h"
void main(){
	MySocket * mysocket= new MySocket();
	mysocket->init();
	mysocket->mybind();
	mysocket->mylisten();
	
	SOCKET socket=mysocket->myaccept();
	
	mysocket->myrecv(socket);
	
	mysocket->myclose();
	system("pause");
	
}

三 遗留问题

1 服务器只能连接一个客户端

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include <Winsock2.h> #include <includes.h> #pragma comment(lib, "ws2_32.lib") ////////////////////////////////////////////////////////// OS_FLAG_GRP *Sem_F;//定义信号量集 INT8U err; //定义一个错误信息 int gaodu=100; void * msgPtr[5]; OS_EVENT *Semp; //消息队列 OS_EVENT *Sempyx; //邮箱 OS_MEM *intBuffer;//定义内存控制块指针 INT8U intPart[50][64];//划分分区及内存块 INT8U *intBlkPtr;//定义指针 void WinSocketServer( ) { WORD wVersionRequested; WSADATA wsaData; //int err1; int sockSrv; SOCKADDR_IN addrSrv; SOCKADDR_IN addrClient;// 连接上的客户端ip地址 int len; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return; } if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) { WSACleanup( ); return; } sockSrv=socket(AF_INET,SOCK_STREAM,0); addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); addrSrv.sin_family=AF_INET; addrSrv.sin_port=htons(6000); bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));// 绑定端口 listen(sockSrv,5); len=sizeof(SOCKADDR); while(1) { //unsigned char mm[2]; SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);// 接受客户端连接,获取客户端的ip地址 // sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));// 组合消息发送出去 intBlkPtr=OSMemGet(intBuffer,&err);//请求内存,获得内存分区指针 recv(sockConn,intBlkPtr,64,0);// 接受客户端消息 OSQPost(Semp, intBlkPtr); //有的数据可能不处理,就对掉了。 closesocket(sockConn);//断开连接 } } #define TASK_STK_SIZE 128 OS_STK AppStk_1[TASK_STK_SIZE]; OS_STK AppStk_2[TASK_STK_SIZE]; OS_STK AppStk_3[TASK_STK_SIZE]; OS_STK AppStk_4[TASK_STK_SIZE]; OS_STK AppStk_5[TASK_STK_SIZE]; OS_STK AppStk_6[TASK_STK_SIZE]; OS_STK AppStk_7[TASK_STK_SIZE]; OS_STK AppStk_8[TASK_STK_SIZE]; void App_Socket(void *p_arg) { while(1) { WinSocketServer( ); //建立socket接收数据 } //OSTimeDlyHMSM(0, 0, 1, 0); //这行是否可以删除 } // 温度,高度,自动驾驶 void App_gaodu_caiji( 详细解释代码
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值