| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 589 人关注过本帖
标题:一个简单的聊天服务器程序(学winsocket的新人机会难得哦!!)
只看楼主 加入收藏
zanzan1986
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:100
专家分:140
注 册:2011-2-22
结帖率:66.67%
收藏
已结贴  问题点数:20 回复次数:2 
一个简单的聊天服务器程序(学winsocket的新人机会难得哦!!)
这是本人用WSAEventSelect()来写的一个I/O异步的模式,发送方式采用流试数据TCP的形式;
程序代码:
#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define WSA_MAXIMUM_EVENTS 60
void RecvData(SOCKET s, char buffer[], int size);
void SendData(SOCKET s, SOCKET a[], DWORD size, char buffer[], int str);
int _tmain(int argc, _TCHAR* argv[])
{

    WSADATA   wsd;
    SOCKET   Socket[WSA_MAXIMUM_EVENTS];                    //建立60个套接字
    WSAEVENT Event[WSA_MAXIMUM_EVENTS];                     //建立60个事件对象句柄
    WSANETWORKEVENTS NetworkEvents;                         //网络事件类型结构
    WSAEVENT NewEvent;                                      //事件对象句柄
    struct sockaddr_in local;                               //网络信息结构
    SOCKET   Accept,Listen;                                 //套接字句柄
    DWORD EventTotal = 0;                                   //事件计数
    DWORD Index,i;                                          //事件句柄引索
    char  buffer[1024];
    local.sin_family  =  AF_INET;
    local.sin_addr.S_un.S_addr = inet_addr("192.168.0.100");
    local.sin_port  =  htons(5150);
    if(WSAStartup(MAKEWORD(2,2),&wsd) != 0)
    {
        printf("add winsocket to failed\n");
        getchar();
        return 0;
    }
    Listen = socket(PF_INET,SOCK_STREAM,0);
    if(Listen == SOCKET_ERROR)
    {
         printf("socket to error!!!\n");
         getchar();
         return 0;
    }
    if(bind(Listen,(PSOCKADDR) &local, sizeof(local)) == SOCKET_ERROR)
    {
         printf("bind to error!!!\n");
         getchar();
         return 0;
    }
    NewEvent = WSACreateEvent();
    WSAEventSelect(Listen,NewEvent,FD_ACCEPT | FD_CLOSE);
    listen(Listen,60);
    Socket[EventTotal] = Listen;
    Event[EventTotal]  = NewEvent;
    EventTotal++;
    while(TRUE)
    {
        Index = WSAWaitForMultipleEvents(EventTotal,Event,FALSE,WSA_INFINITE,FALSE);       
        WSAEnumNetworkEvents(
            Socket[Index - WSA_WAIT_EVENT_0],Event[Index - WSA_WAIT_EVENT_0],&NetworkEvents);

        if(NetworkEvents.lNetworkEvents & FD_ACCEPT)
        {
            if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT] != 0)
           {
                printf("FD_ACCEPT failed with error %d\n",NetworkEvents.iErrorCode[FD_ACCEPT_BIT]);
                getchar();
               // break;
           }

            Accept = accept(Socket[Index - WSA_WAIT_EVENT_0],NULL,NULL);

            if(EventTotal > WSA_MAXIMUM_WAIT_EVENTS)
            {
                printf("Too many connections\n");
                closesocket(Accept);
                getchar();
                //break;
            }

            NewEvent = WSACreateEvent();
            WSAEventSelect(Accept,NewEvent,FD_READ | FD_CLOSE);
            Event[EventTotal] = NewEvent;
            Socket[EventTotal] = Accept;
            EventTotal++;
            printf("Socket %d connected\n",Accept);
        }
        if(NetworkEvents.lNetworkEvents & FD_READ)
        {
           if(NetworkEvents.iErrorCode[FD_READ_BIT] != 0)
           {
                printf("FD_READ failed with error %d\n",NetworkEvents.iErrorCode[FD_READ_BIT]);
                 //getchar();
                //break;
            }
           else
           {
           //printf("read data to:");
               RecvData(Socket[Index - WSA_WAIT_EVENT_0],buffer,1024);
               i = *(int*)buffer;
               printf("\n%d号准备发送%d个字节\n",Index - WSA_WAIT_EVENT_0,i);
               if(buffer[4]) SendData(Socket[Index - WSA_WAIT_EVENT_0],Socket,EventTotal,buffer,i);
           }
        }
        if(NetworkEvents.lNetworkEvents & FD_CLOSE)
        {
           if(NetworkEvents.iErrorCode[FD_CLOSE_BIT] != 0)
           {
                printf("FD_READ failed with error %d\n",NetworkEvents.iErrorCode[FD_CLOSE_BIT]);
                 getchar();
                //break;
            }
           
            closesocket(Socket[Index - WSA_WAIT_EVENT_0]);
           
            WSACloseEvent(Event[Index - WSA_WAIT_EVENT_0]);
            printf("COLSE SOCKET..................\n");
            for(i = Index - WSA_WAIT_EVENT_0; i < (int) EventTotal; i++)
            {
                   Socket[i] = Socket[i + 1];
                   Event[i]  = Event[i + 1];
            }
            EventTotal--;
        }

    }
    closesocket(Listen);
    WSACleanup();
    return 0;
}


void RecvData(SOCKET s, char buffer[], int size)
{
    int i,Index,Length;
    Length = i = 0;
    do
    {
        Index = recv(s,&buffer[Length],size,0);
        if(Index == SOCKET_ERROR)
        {
            buffer[4] = 0;
            break;
        }
        if(Index > 4 && i == 0)
        {
            i = *((int*) buffer);
            printf("接收%d字节数据\n",i);
        }
        Length += Index;
        if(Length > 1024)
        {
            printf("已超出接收范围数据\n");
            break;
        }
    }while(Length < i);
    buffer[Length] = 0;
    printf("接收字符串:%s",&buffer[4]);
}

void SendData(SOCKET s, SOCKET a[], DWORD size, char buffer[], int str)
{
    DWORD i;
    int Index,l,ret;
    printf("共有%d组套节字\n",size);
    for(i = 1; i < size; i++)
    {
        if(a[i] != s)
        {
            printf("开始发给%d套节字\n",a[i]);
            l = str;
            Index = 0;
            printf("sending.....");
            do
            {
                ret = send(a[i],&buffer[Index],str,0);
                if(ret == SOCKET_ERROR)
                {
                    printf("send to fialed\n");
                    break;
                }
                l -= ret;
                Index += ret;
                printf("....");
            }while(l > 0);
            printf("\n");
        }
    }
}

搜索更多相关主题的帖子: comment winsocket 
2012-10-17 22:30
ycb_2008
Rank: 1
等 级:新手上路
帖 子:11
专家分:5
注 册:2012-10-11
收藏
得分:5 
路过,帮顶。~~
2012-10-18 09:54
pengzhuo2008
Rank: 2
来 自:湖南
等 级:论坛游民
帖 子:29
专家分:68
注 册:2012-9-28
收藏
得分:15 
楼主
你其实可以再封装一下的。
我将这个socket编程,直接封装了四个函数
一个是服务器端的初始化相关的配置函数, 返回一个socket, 另一个是客户端的
然后剩下的两个就是你这里的发送和接收

这样子, 下次使用的时候,果断的调用函数,传进相应的参数就OK了。
省时省力省心。

1+1=2
2012-10-18 09:59
快速回复:一个简单的聊天服务器程序(学winsocket的新人机会难得哦!!)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.042113 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved