初始化如下:BOOL CMyChatDlg::OnInitDialog()
{
// TODO: Add extra initialization here
Server = socket(AF_INET,SOCK_STREAM,0);           
Serveraddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
Serveraddr.sin_family=AF_INET;
Serveraddr.sin_port=htons(8001);
bind(Server,(SOCKADDR*)&Serveraddr,sizeof(SOCKADDR));  //socket绑定端口
listen(Server,5);   //socket端口进入监听模式
RECVPARAM *pRecvParam = new RECVPARAM;
          pRecvParam->sock = Server;
pRecvParam->hwnd = m_hWnd;
HANDLE hThread = CreateThread(NULL,0,ThreadProc,(LPVOID)pRecvParam,0,NULL);
CloseHandle(hThread);
return TRUE; 在连接按钮事件中 (连接指定IP)void CMyChatDlg::OnButtonLink() 
{
// TODO: Add your control notification handler code here
CString ip;
m_IP.GetWindowText(ip);
MessageBox("before link");
Client=socket(AF_INET,SOCK_STREAM,0);
DWORD dwip;
if((dwip=inet_addr(ip))==INADDR_NONE)
{
MessageBox("IP赋值错误!");
return ;
}
Clientaddr.sin_addr.S_un.S_addr = dwip; //ip地址
Clientaddr.sin_family=AF_INET;          //使用TCP/IP协议
         Clientaddr.sin_port = htons(8001);      //端口设置
if(connect(Client,(SOCKADDR*)&Clientaddr,sizeof(Clientaddr)) == SOCKET_ERROR)
        {
MessageBox("无法连接服务器!");
              return ;
}
}在发送按钮事件中 UpdateData(true);
send(Client,m_send,sizeof(m_send)+1,0);在线程函数中(接收数据线程)DWORD WINAPI CMyChatDlg::ThreadProc(LPVOID lpParameter)
{

SOCKET sock = ((RECVPARAM*)lpParameter)->sock;
HWND hwnd = ((RECVPARAM*)lpParameter)->hwnd; SOCKADDR_IN addrFrom;
int len = sizeof(SOCKADDR); char recvBuf[200];
char tempBuf[300];
int retval;
while(1)
{
SOCKET sockConn=accept(sock,(SOCKADDR*)&addrFrom,&len);
retval = recv(sockConn,recvBuf,200,0);
if(retval==SOCKET_ERROR)
break;
sprintf(tempBuf," %s说 : %s",inet_ntoa(addrFrom.sin_addr),recvBuf);
::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
}
return 0;
}
这样的话,要每次都连接才能接收到发送出的数据是有tcp通讯的连接到底是怎么连接的?
我这个线程函数能不能同时和多个ip进行聊天?
请大家指教一下

解决方案 »

  1.   

    可以啊,你listen不是设置了5个吗,只需为每一个链接新增一个socket来保持通信,
      

  2.   

    这样做有问题的,你难道对每个socket只接收一次?客户端不多的话,可以每个socket建立一个接收线程,循环接收
      

  3.   

    这样的话,要每次都连接才能接收到发送出的数据是有tcp通讯的连接到底是怎么连接的?
    我这个线程函数能不能同时和多个ip进行聊天?
    请大家指教一下
    你这个线程函数可以与多个IP聊天,但是会出现内存泄露,你要每个连接的新的SOCKET 用数组或者链表管理起来然后,你就可以要和哪个聊天,就把对应的SOCKET找出来,对他发数据,懂了没?
      

  4.   

    如ls所言,你对每一个到来的连接创建一个线程,这个线程专门用来处理与客户端的通讯。当然效率不高。要想高效的话参考socket IO的模型select,WSAAsyncSelect,WSAEventSelect,Overlapped IO,IOCP
      

  5.   

    你的代码有严重的问题:DWORD WINAPI CMyChatDlg::ThreadProc(LPVOID lpParameter)
    {
        
        SOCKET sock = ((RECVPARAM*)lpParameter)->sock;
        HWND hwnd = ((RECVPARAM*)lpParameter)->hwnd;    SOCKADDR_IN addrFrom;
        int len = sizeof(SOCKADDR);    char recvBuf[200];
        char tempBuf[300];
        int retval;
        while(1)
        {
            SOCKET sockConn=accept(sock,(SOCKADDR*)&addrFrom,&len);//在这里会阻塞,等待连接
            retval = recv(sockConn,recvBuf,200,0); //有连接过来,接收数据
            if(retval==SOCKET_ERROR)
                break;
            sprintf(tempBuf," %s说 : %s",inet_ntoa(addrFrom.sin_addr),recvBuf); 
            ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
            //完成过,又回到WHILE里的第一句,等待连接,所以会每连接一次才回接收到数据
        }
        return 0;
    }
      

  6.   

    代码应该改成这样,需一个ACCEPT线程和一个READ线程DWORD WINAPI CMyChatDlg::ThreadProc(LPVOID lpParameter)
    {
        
        SOCKET sock = ((RECVPARAM*)lpParameter)->sock;
        HWND hwnd = ((RECVPARAM*)lpParameter)->hwnd;    SOCKADDR_IN addrFrom;
        int len = sizeof(SOCKADDR);    char recvBuf[200];
        char tempBuf[300];
        int retval;
        while(1)
        {
            SOCKET sockConn=accept(sock,(SOCKADDR*)&addrFrom,&len);//在这里会阻塞,等待连接
             CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)readProc, (void *)sockConn, 0, NULL);
        }
        return 0;
    }DWORD CMyChatDlg::readProc(LPVOID lparam)
    {
    char recvBuf[200];
    int retval;
    SOCKET cliSock = (SOCKET)lparam;
    while(1) {
            retval = recv(sockConn,recvBuf,200,0);
            if(retval==SOCKET_ERROR)
                break;
            recvBuf[retval]='\0';
            sprintf(tempBuf," %s说 : %s",inet_ntoa(addrFrom.sin_addr),recvBuf); 
            ::PostMessage(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf);
    }
    return 0;
    }
      

  7.   

    连接如何关闭?  没有地方调用close函数。