套接口复用实现的聊天室的程序

//只要按要求将程序中的注释部份改为注释所述就可以运行了

/*VC下编写多线程程序除了包含头文件

       #include <process.h>

一定要记住如下的设定,不然编译会出错的://Project->Settings->C/C++->CategoryCode GenerationUse run-time libraryMultithreaded */

 

//TCP:client.cpp

#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>
#include <process.h>
#define MSG_MAX_SIZE 1024

void __cdecl Get_keybeard_input(void*param)
{
SOCKET Sock=(SOCKET)param;
while(1)
{
   char info[MSG_MAX_SIZE];
   gets(info);
   int ret=send(Sock,info,MSG_MAX_SIZE,0);
   if(ret==SOCKET_ERROR)
   {
    printf("send()failed:%d/n",WSAGetLastError());
    closesocket(Sock);
      WSACleanup();
      continue;
   }
}
}


int main()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
   printf("Error at WSAStartup()/n");
   return -1;
}

SOCKET Sock;
    Sock = socket(AF_INET, SOCK_STREAM, 0);
if (Sock == INVALID_SOCKET)
{
   printf("Error at socket(): %ld/n", WSAGetLastError());
   WSACleanup();
   return -1;
}

sockaddr_in service;
service.sin_family = AF_INET;
service.sin_port = htons(27015);
service.sin_addr.s_addr = inet_addr("ip");           //将此处的IP改为服务器程序运行的主机IP(用点分十进制)

int err=connect(Sock,(SOCKADDR*) &service, sizeof(service));
if(err==SOCKET_ERROR)
{
   printf("connect() failed: %ld/n", WSAGetLastError());
   closesocket(Sock);
   WSACleanup();
   return -1;
}

_beginthread(Get_keybeard_input,0,(void*)Sock);
char recv_buf[MSG_MAX_SIZE];
while(1)
{
   memset(recv_buf,0,MSG_MAX_SIZE);
   int rlen=recv(Sock,recv_buf,MSG_MAX_SIZE,0);
   if(rlen==0) break;
   if(rlen==SOCKET_ERROR)
   {
            printf("recv() failed: %ld/n", WSAGetLastError());
      closesocket(Sock);
      WSACleanup();
      return -1;
   }
   puts(recv_buf);
}
closesocket(Sock);
WSACleanup();
return 0;
}

 

 

 

//TCP:server.cpp

#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <stdio.h>
int main()
{
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0)
{
   printf("Error at WSAStartup()/n");
   return -1;
}

SOCKET ListenSocket;
ListenSocket = socket(AF_INET, SOCK_STREAM, 0);
if (ListenSocket == INVALID_SOCKET)
{
   printf("Error at socket(): %ld/n", WSAGetLastError());
   WSACleanup();
   return -1;
}

sockaddr_in service;
service.sin_family = AF_INET;
service.sin_port = htons(27015);
service.sin_addr.s_addr = inet_addr("IP");     //将此处的IP改为的主机IP(用点分十进制表示)

if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR)
{
   printf("bind() failed: %ld/n", WSAGetLastError());
   closesocket(ListenSocket);
   WSACleanup();
   return -1;
}
if (listen( ListenSocket, 1 ) == SOCKET_ERROR)
{
   printf("listen() failed: %ld/n", WSAGetLastError());
   closesocket(ListenSocket);
   WSACleanup();
   return -1;
}

SOCKET client[FD_SETSIZE - 1];  
for(int i = 0;i < FD_SETSIZE;i++)  
{
   client[i] =INVALID_SOCKET;
}

fd_set   rset, allset;   //allset--所有套接口, rset--可读套接口
FD_ZERO(&allset);  
FD_SET(ListenSocket, &allset);  

#define MSG_MAX_SIZE 1024
char   buf[FD_SETSIZE - 1][MSG_MAX_SIZE];  

for(;;)
{  
   rset = allset;   //structure assignment
    int ret = select(0,&rset,NULL,NULL,NULL);
           if (ret == SOCKET_ERROR)
   {  
    printf("select() failed: %ld/n", WSAGetLastError());
    break;
   }  
   if (ret == 0) {
    continue;
   }
   if(FD_ISSET(ListenSocket, &rset))
   {  
    struct   sockaddr_in   cliaddr;  
    int clilen   =   sizeof(cliaddr);  
    SOCKET sockConn = accept(ListenSocket,(sockaddr *)&cliaddr, &clilen);
    if (sockConn == SOCKET_ERROR)
    {
     printf("accept() failed: %ld/n", WSAGetLastError());
     break; //continue
    }  
    for(i = 0; i < FD_SETSIZE - 1; i++)
    {
     if(client[i] == INVALID_SOCKET)
     {  
      client[i]   =   sockConn;  
      break;  
     }  
    } //for end
    if(i < FD_SETSIZE - 1)
    {  
     FD_SET(sockConn, &allset);  
    }  
    else{
     printf("too   many   clients");  
     closesocket(sockConn);
    }
    //为了理解容易,可以删除下面4行
    ret --;
    if(ret   <=   0)
    {
     continue;  
    }
   }// if (FD_ISSET(ListenSocket, &rset)) end

   for(i = 0; i < FD_SETSIZE - 1; i++)  
   {  
    if ((client[i] != INVALID_SOCKET) &&
      FD_ISSET(client[i], &rset))  
    {  
     memset(buf[i], 0 , MSG_MAX_SIZE);
     int nByte = recv(client[i], buf[i], MSG_MAX_SIZE, 0);
     if (nByte == SOCKET_ERROR)
     {
      printf("recv() failed: %ld/n", WSAGetLastError());
      FD_CLR(client[i],&allset);  
      closesocket(client[i]);
      client[i] = INVALID_SOCKET;
      continue;
     }
     if (nByte == 0)
     {
      FD_CLR(client[i],&allset);  
      closesocket(client[i]);
      client[i] = INVALID_SOCKET;
      continue;
     }
     //do the request
     for(int j=0;j<FD_SETSIZE-1;j++)
     {
      if(i!=j)
      int ret=send(client[j],buf[i],MSG_MAX_SIZE,0);
      if(ret==SOCKET_ERROR)
      {
       printf("send()failed:%d/n",WSAGetLastError());
       continue;
      }

     }
    }
   }//loop client end
}// for(;;) end
closesocket(ListenSocket);
WSACleanup();
return 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值