想实现这样的一个功能:在服务器端有一个控制台程序,与多个客户端程序通讯,其中主线程有一个socket绑定在一个固定端口上。每启动一个客户端程序(通过客户端的新的socket连接请求判定),server端就新开启一个线程,并在其中创建一个socket与该客户端的socket通讯,直到客户端程序关闭。主线程中的socket直到应用程序退出时才关闭.VC++不太熟悉,不太会写创建新线程并用一个新的socket接受客户端socket连接请求这一块的代码。比如,我的代码如下,哪位能帮我加一点代码,实现这一个对我来说是难点的地方。谢谢!
#include "StdAfx.h"
#include <stdio.h>int main(int argc,char* argv[])
{
//initialize Winsock
WSADATA wsaData;
int iRet=WSAStartup(MAKEWORD(2,2),&wsaData);
if(iRet!=NO_ERROR)
printf("Error at WSAStartup()\n");

//create a socket
SOCKET m_socket;
m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(m_socket==INVALID_SOCKET)
{
printf("Error at socket():%ld\n",WSAGetLastError());
WSACleanup();
return 0;
} //bind a socket
sockaddr_in service;
service.sin_family=AF_INET;
service.sin_addr.s_addr=inet_addr("172.16.3.250");
service.sin_port=htons(2501); if(bind(m_socket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
{
printf("bind() failed.\n");
closesocket(m_socket);
return 0;
}
else
printf("bind OK.\n"); //listen on a socket
if(listen(m_socket,1)==SOCKET_ERROR)
printf("Error listening on socket.\n");
else
printf("listening ok.\n"); //accept a connection
SOCKET AcceptSocket;

printf("Waiting for a client to connect...\n");
while(1)  
{        
AcceptSocket=SOCKET_ERROR;
while(AcceptSocket==SOCKET_ERROR)
{
                            AcceptSocket=accept(m_socket,NULL,NULL); 
}
                   //在这里开启新线程?
printf("Client Connected.\n");
m_socket=AcceptSocket;
break;
}
// Receiving data
//return
return 0;}

解决方案 »

  1.   

    ...
    while(1)  
    {        
    AcceptSocket=SOCKET_ERROR;
    while(AcceptSocket==SOCKET_ERROR)
    {
                                AcceptSocket=accept(m_socket,NULL,NULL); 
    }
    DWORD dwThreadId;
        HANDLE hThread; 

    hThread= CreateThread(NULL,0,_thread,(LPVOID)&AcceptSocket,0,&dwThreadId);                
        if (hThread== NULL) 
    {
    printf( "CreateThread thread() failed.\n" ); 
    }
                       //在这里开启新线程?
    printf("Client Connected.\n");
    m_socket=AcceptSocket;
    break;
    }
    // Receiving dataDWORD  WINAPI _thread(LPVOID prama)
    {
    SOCKET AcceptSocket=(SOCKET)*(LPVOID)prama;
    ...return 0;
    }
      

  2.   

    参考一下这个代码吧.不过是java写的多线程服务器程序举例 以下是我们在项目中采用的多线程服务器程序的架构,可以在此基础上对命令进行扩充。本例未涉及数据库。如果在线程运行中需要根据用户指令对数据库进行更新操作,则应注意线程间的同步问题,使同一更新方法一次只能由一个线程调用。这里我们有两个类,receiveServer包含启动代码(main()),并初始化ServerSocket的实例,在accept方法返回用户请求后,将返回的套接字(Socket)交给生成的线程类serverThread的实例,直到该用户结束连接。 //类receiveServer 
    import java.io.*; 
    import java.util.*; 
    import java.net.*; public class receiveServer{ final int RECEIVE_PORT=9090; //该服务器的端口号 //receiveServer的构造器public receiveServer() {ServerSocket rServer=null; //ServerSocket的实例 Socket request=null; //用户请求的套接字Thread receiveThread=null; try{ rServer=new ServerSocket(RECEIVE_PORT); //初始化ServerSocket System.out.println("Welcome to the server!"); System.out.println(new Date()); System.out.println("The server is ready!"); System.out.println("Port: "+RECEIVE_PORT); while(true){ //等待用户请求 request=rServer.accept(); //接收客户机连接请求receiveThread=new serverThread(request); //生成serverThread的实例 
    receiveThread.start(); //启动serverThread线程 


    catch(IOException e){ System.out.println(e.getMessage()) ; 
    } } public static void main(String args[]){ new receiveServer(); } //end of main} //end of class//类serverThreadimport java.io.*; import java.net.*; class serverThread extends Thread {Socket clientRequest; //用户连接的通信套接字BufferedReader input; //输入流PrintWriter output; //输出流 public serverThread(Socket s) { //serverThread的构造器 this.clientRequest=s; //接收receiveServer传来的套接字 InputStreamReader reader; OutputStreamWriter writer; try{ //初始化输入、输出流 reader=new InputStreamReader(clientRequest.getInputStream()); writer=new OutputStreamWriter(clientRequest.getOutputStream()); input=new BufferedReader(reader); output=new PrintWriter(writer,true); }catch(IOException e){ System.out.println(e.getMessage());} output.println("Welcome to the server!"); //客户机连接欢迎词 output.println("Now is: "+new java.util.Date()+" "+ "Port:"+clientRequest.getLocalPort()); output.println("What can I do for you?"); } public void run(){ //线程的执行方法 String command=null; //用户指令 String str=null; boolean done=false; while(!done){ try{str=input.readLine(); //接收客户机指令 }catch(IOException e){ System.out.println(e.getMessage());} command=str.trim().toUpperCase(); if(str==null    command.equals("QUIT")) //命令quit结束本次连接 done=true; else if(command.equals("HELP")){ //命令help查询本服务器可接受的命令 output.println("query"); output.println("quit"); output.println("help"); } else if(command.startsWith("QUERY")){ //命令query output.println("OK to query something!"); }//else if …….. //在此可加入服务器的其他指令 else if(!command.startsWith("HELP") && !command.startsWith("QUIT") && !command.startsWith("QUERY")){output.println("Command not Found! Please refer to the HELP!"); } } //end of while try { clientRequest.close(); //关闭套接字 }catch(IOException e){ System.out.println(e.getMessage()); }command=null; } 
    //end of run 启动该服务器程序后,可用telnet machine port命令连接,其中machine为本机名或地址,port为程序中指定的端口。也可以编写特定的客户机软件通过TCP的Socket套接字建立连接。 
      

  3.   

    to rockrabbit (紫色石头) ,就是在你标的那个位置启动一个线程负责同客户端通信啊,当接收完数据,或客户端退出,就可以终止线程了
      

  4.   

    Beginning Winsock Programming - Multithreaded TCP server with client
    http://www.codeproject.com/internet/winsockintro03.asp
      

  5.   

    谢谢楼上各位,我改成这个样子了,但奇怪,怎么接收不到客户端发来的数据:
    #include "StdAfx.h"
    #include <stdio.h>DWORD WINAPI AnswerThread(LPVOID lparam)
    {
    SOCKET ClientSocket=(SOCKET)(LPVOID)lparam; int bytesRecv;
    char recvbuf[32]=""; while(1)
    {
    bytesRecv=SOCKET_ERROR;
    for(int i=0;i<(int)strlen(recvbuf);i++)
    {
    recvbuf[i]='\0';
    }
    bytesRecv=SOCKET_ERROR;
    while(bytesRecv==SOCKET_ERROR)
    {
    bytesRecv=recv(ClientSocket,recvbuf,32,0);
    }
    send(ClientSocket,recvbuf,strlen(recvbuf),0);
    printf("%s",recvbuf);
    } return 0;
    }int main(int argc,char* argv[])
    {
    //initialize Winsock
    WSADATA wsaData;
    int iRet=WSAStartup(MAKEWORD(2,2),&wsaData);
    if(iRet!=NO_ERROR)
    printf("Error at WSAStartup()\n");

    //create a socket
    SOCKET m_socket;
    m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(m_socket==INVALID_SOCKET)
    {
    printf("Error at socket():%ld\n",WSAGetLastError());
    WSACleanup();
    return 0;
    } //bind a socket
    sockaddr_in service;
    service.sin_family=AF_INET;
    service.sin_addr.s_addr=inet_addr("172.16.3.250");
    service.sin_port=htons(2501); if(bind(m_socket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR)
    {
    printf("bind() failed.\n");
    closesocket(m_socket);
    return 0;
    }
    else
    printf("bind OK.\n"); //listen on a socket
    if(listen(m_socket,20)==SOCKET_ERROR)
    printf("Error listening on socket.\n");
    else
    printf("listening ok.\n"); //accept a connection
    SOCKET AcceptSocket;

    printf("Waiting for a client to connect...\n");
    while(1)
    {
    AcceptSocket=SOCKET_ERROR;
    while(AcceptSocket==SOCKET_ERROR)
    {
    AcceptSocket=accept(m_socket,NULL,NULL);
    }
    printf("Client Connected.\n");

    DWORD dwThreadId;
    HANDLE hThread;

    hThread=CreateThread(NULL,NULL, AnswerThread,
    (LPVOID)&AcceptSocket,0,&dwThreadId);
    if(hThread==NULL)
    {
    printf("CreatThread AnswerThread() failed.\n");
    }
    else
    {
    printf("CreateThread OK.\n");
    }
    //m_socket=AcceptSocket;
    //break;
    }

    return 0;
    }
      

  6.   

    哦,非常感谢shootingstars和geland二位。不过geland给的代码有两个小问题,看了shootingstars给的连接后,现在解决了:
    ----
    (1)
    hThread=CreateThread(NULL,NULL, AnswerThread,
    (LPVOID)&AcceptSocket,0,&dwThreadId);
    应该改为:
    hThread=CreateThread(NULL,NULL, AnswerThread,
    (LPVOID)AcceptSocket,0,&dwThreadId);(2):
    SOCKET ClientSocket=(SOCKET)(LPVOID)lparam;就可以了。