引用 | 編輯
MarkTzen
2005-12-18 01:35 |
1樓
▲ |
簡單的TCP stream 的程式,client & server。
參考一下… Client Side: 複製程式 // // Client.cpp // // Extremely simple, stream client example. // Works in conjunction with Server.cpp. // // The program attempts to connect to the server and port // specified on the command line. The Server program prints // the needed information when it is started. Once connected, // the program sends data to the server, waits for a response // and then exits. // // Compile and link with wsock32.lib // // Pass the server name and port number on the command line. // // Example: Client MyMachineName 2000 // #include <stdio.h> #include <winsock.h> // Function prototype void StreamClient(char *szServer, short nPort); // Helper macro for displaying errors #define PRINTERROR(s) \ fprintf(stderr,"\n%: %d\n", s, WSAGetLastError()) //////////////////////////////////////////////////////////// void main(int argc, char **argv) { WORD wVersionRequested = MAKEWORD(1,1); WSADATA wsaData; int nRet; short nPort; // // Check for the host and port arguments // if (argc != 3) { fprintf(stderr,"\nSyntax: client ServerName PortNumber\n"); return; } nPort = atoi(argv[2]); // // Initialize WinSock and check the version // nRet = WSAStartup(wVersionRequested, &wsaData); if (wsaData.wVersion != wVersionRequested) { fprintf(stderr,"\n Wrong version\n"); return; } // // Go do the stuff a stream client does // StreamClient(argv[1], nPort); // // Release WinSock // WSACleanup(); } //////////////////////////////////////////////////////////// void StreamClient(char *szServer, short nPort) { printf("\nStream Client connecting to server: %s on port: %d", szServer, nPort); // // Find the server // LPHOSTENT lpHostEntry; lpHostEntry = gethostbyname(szServer); if (lpHostEntry == NULL) { PRINTERROR("gethostbyname()"); return; } // // Create a TCP/IP stream socket // SOCKET theSocket; theSocket = socket(AF_INET, // Address family SOCK_STREAM, // Socket type IPPROTO_TCP); // Protocol if (theSocket == INVALID_SOCKET) { PRINTERROR("socket()"); return; } // // Fill in the address structure // SOCKADDR_IN saServer; saServer.sin_family = AF_INET; saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list); // ^ Server's address saServer.sin_port = htons(nPort); // Port number from command line // // connect to the server // int nRet; nRet = connect(theSocket, // Socket (LPSOCKADDR)&saServer, // Server address sizeof(struct sockaddr));// Length of server address structure if (nRet == SOCKET_ERROR) { PRINTERROR("socket()"); closesocket(theSocket); return; } // // Send data to the server // char szBuf[256]; strcpy(szBuf, "From the Client"); nRet = send(theSocket, // Connected socket szBuf, // Data buffer strlen(szBuf), // Length of data 0); // Flags if (nRet == SOCKET_ERROR) { PRINTERROR("send()"); closesocket(theSocket); return; } // // Wait for a reply // nRet = recv(theSocket, // Connected socket szBuf, // Receive buffer sizeof(szBuf), // Size of receive buffer 0); // Flags if (nRet == SOCKET_ERROR) { PRINTERROR("recv()"); closesocket(theSocket); return; } // // Display the received data // printf("\nData received: %s", szBuf); closesocket(theSocket); return; } Client Side: 複製程式 // // Server.cpp // // Extremely simple, stream server example. // Works in conjunction with Client.cpp. // // The program sets itself up as a server using the TCP // protoocl. It waits for data from a client, displays // the incoming data, sends a message back to the client // and then exits. // // Compile and link with wsock32.lib // // Pass the port number that the server should bind() to // on the command line. Any port number not already in use // can be specified. // // Example: Server 2000 // #include <stdio.h> #include <winsock.h> // Function prototype void StreamServer(short nPort); // Helper macro for displaying errors #define PRINTERROR(s) \ fprintf(stderr,"\n%: %d\n", s, WSAGetLastError()) //////////////////////////////////////////////////////////// void main(int argc, char **argv) { WORD wVersionRequested = MAKEWORD(1,1); WSADATA wsaData; int nRet; short nPort; // // Check for port argument // if (argc != 2) { fprintf(stderr,"\nSyntax: server PortNumber\n"); return; } nPort = atoi(argv[1]); // // Initialize WinSock and check version // nRet = WSAStartup(wVersionRequested, &wsaData); if (wsaData.wVersion != wVersionRequested) { fprintf(stderr,"\n Wrong version\n"); return; } // // Do the stuff a stream server does // StreamServer(nPort); // // Release WinSock // WSACleanup(); } //////////////////////////////////////////////////////////// void StreamServer(short nPort) { // // Create a TCP/IP stream socket to "listen" with // SOCKET listenSocket; listenSocket = socket(AF_INET, // Address family SOCK_STREAM, // Socket type IPPROTO_TCP); // Protocol if (listenSocket == INVALID_SOCKET) { PRINTERROR("socket()"); return; } // // Fill in the address structure // SOCKADDR_IN saServer; saServer.sin_family = AF_INET; saServer.sin_addr.s_addr = INADDR_ANY; // Let WinSock supply address saServer.sin_port = htons(nPort); // Use port from command line // // bind the name to the socket // int nRet; nRet = bind(listenSocket, // Socket (LPSOCKADDR)&saServer, // Our address sizeof(struct sockaddr)); // Size of address structure if (nRet == SOCKET_ERROR) { PRINTERROR("bind()"); closesocket(listenSocket); return; } // // This isn't normally done or required, but in this // example we're printing out where the server is waiting // so that you can connect the example client. // int nLen; nLen = sizeof(SOCKADDR); char szBuf[256]; nRet = gethostname(szBuf, sizeof(szBuf)); if (nRet == SOCKET_ERROR) { PRINTERROR("gethostname()"); closesocket(listenSocket); return; } // // Show the server name and port number // printf("\nServer named %s waiting on port %d\n", szBuf, nPort); // // Set the socket to listen // printf("\nlisten()"); nRet = listen(listenSocket, // Bound socket SOMAXCONN); // Number of connection request queue if (nRet == SOCKET_ERROR) { PRINTERROR("listen()"); closesocket(listenSocket); return; } // // Wait for an incoming request // SOCKET remoteSocket; printf("\nBlocking at accept()"); remoteSocket = accept(listenSocket, // Listening socket NULL, // Optional client address NULL); if (remoteSocket == INVALID_SOCKET) { PRINTERROR("accept()"); closesocket(listenSocket); return; } // // We're connected to a client // New socket descriptor returned already // has clients address // // Receive data from the client // memset(szBuf, 0, sizeof(szBuf)); nRet = recv(remoteSocket, // Connected client szBuf, // Receive buffer sizeof(szBuf), // Lenght of buffer 0); // Flags if (nRet == INVALID_SOCKET) { PRINTERROR("recv()"); closesocket(listenSocket); closesocket(remoteSocket); return; } // // Display received data // printf("\nData received: %s", szBuf); // // Send data back to the client // strcpy(szBuf, "From the Server"); nRet = send(remoteSocket, // Connected socket szBuf, // Data buffer strlen(szBuf), // Lenght of data 0); // Flags // // Close BOTH sockets before exiting // closesocket(remoteSocket); closesocket(listenSocket); return; } Description: =========================================================== Stream, connection-oriented client and server example. This demonstrates the steps required for a VERY simple server and client using stream sockets. Both programs can be run on one machine. If you dial in to your network, you must be connected even if you are going to run the programs on one machine. Example: First, run Server in the first DOS box, server 2000 The server program will bind to port 2000 and print it's host name to stdout. "Server named MachineName waiting on port 2000" Then run Client in a second DOS box, using the host name and port number printed out in step 1. client MachineName 2000 At that point, the client will send the string "From the client" to the server. The server will then respond by sending the string "From the server" back to the client. Both programs will then exit. =========================================================== SERVER.CPP Server source code. Compile and link with WSOCK32.LIB Only uses C++ so that variables can be declared near where they are used for the first time. CLIENT.CPP Client source code. Compile and link with WSOCK32.LIB Only uses C++ so that variables can be declared near where they are used for the first time. =========================================================== x0 |