原創(chuàng) 2014年01月09日 01:10:23 招著官方教程一步步做
主要函數(shù)或步驟: - WSAStartup, 初始化,WSACleanup,結(jié)束
- socket(, ,) 構(gòu)造函數(shù),要有socket的instance才能實現(xiàn)傳輸
- send()
- recv()
- listen(), server端開始要監(jiān)聽自己的端口號有沒有被連接
- bind(),server的用來listen()的socket綁定address
- accept(),如果沒有client要連接,server在調(diào)用時就阻塞,有client要連接,就從這個要連接的隊列里取出然后accept,然后server產(chǎn)生一個新的socket,而之前在listen()的socket是和這個不一樣的,微軟為何要弄兩個socket出來呢,網(wǎng)上有一些解釋,似乎是為了使用時更清楚一點
全部代碼再后面可以直接找到 運行:先運行server的exe,再運行client的exe 這樣就學會了基本的C/S傳輸
然后再加入文件操作:在server打開一個文件,從文件里讀入內(nèi)容,一個個包傳過去,一直讀到文件結(jié)束;在client創(chuàng)建一個用來接收傳輸內(nèi)容的文件,一個個包接收過來,接收過來的內(nèi)容寫在這個文件里。 以下是我用官網(wǎng)代碼修改后的文件傳輸系統(tǒng) - /*server.cpp*/
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
-
- #include <Windows.h>
- #include <WinSock2.h>
- #include <WS2tcpip.h>
- #include <IPHlpApi.h>
- #include <cstdio>
-
- #pragma comment (lib, "Ws2_32.lib")
-
- #define DEFAULT_PORT "27015"
- #define DEFAULT_BUFLEN 512
-
-
-
- int main ()
- {
- int iResult, iSendResult;
- WSADATA wsaData;
- struct addrinfo *result = NULL, *ptr = NULL, hints;
- char temp[DEFAULT_BUFLEN];
-
- printf("input the file you want to transfer\n");
- scanf("%s", temp);
- //strcpy(temp, "input.txt");
-
- // open file
- FILE * fp = fopen(temp, "rb"); // binary mode for read
- if(fp == NULL)
- {
- printf("open file %s failed\n", temp);
- return -1;
- }
-
- if(WSAStartup(MAKEWORD(2, 2), &wsaData))
- {
- printf("server WSAStartup failed: %d\n", iResult);
- return 1;
- }
-
- ZeroMemory(&hints, sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_flags = AI_PASSIVE; // caller to bind
-
- // resolve the local address and port to be used by user
- iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
- if(iResult != 0)
- {
- printf("server getaddrinfo faild: %d\n", iResult);
- WSACleanup();
- return 1;
- }
-
- // create a socket for server
- SOCKET ListenSocket = INVALID_SOCKET;
- ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
- if(ListenSocket == INVALID_SOCKET)
- {
- printf("server failed at socket(): %ld\n", WSAGetLastError());
- freeaddrinfo(result);
- WSACleanup();
- return 1;
- }
-
- // bind a socket
- iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
- if(iResult == SOCKET_ERROR)
- {
- printf("server bind faild: %ld\n", WSAGetLastError());
- freeaddrinfo(result);
- closesocket(ListenSocket);
- WSACleanup();
- return 1;
- }
- freeaddrinfo(result); // once bind, no longer needed
-
- // listen on a socket
- if(listen(ListenSocket, SOMAXCONN))
- {
- printf("server listen socket failed %ld\n", WSAGetLastError());
- closesocket(ListenSocket);
- WSACleanup();
- return 1;
- }
-
-
- // accept a connection
- sockaddr_in client_addr;
- int nlen;
- SOCKET ClientSocket = INVALID_SOCKET;
- ClientSocket = accept(ListenSocket, NULL, NULL);
- if(ClientSocket == INVALID_SOCKET)
- {
- printf("server accept failed: %ld\n",WSAGetLastError());
- closesocket(ListenSocket);
- WSACleanup();
- return 1;
- }
- //char *ip = inet_ntoa(client_addr.sin_addr);
- //printf("establish connection to server %s\n", ip);
-
- // no longer need
- closesocket(ListenSocket);
-
- // file operation and send data
-
- int num = 0;
- while(!feof(fp))
- {
- num = fread(temp, 1, DEFAULT_BUFLEN, fp);
- send(ClientSocket, temp, num, 0);
- }
- printf("server file transfer success\n");
-
- fclose(fp);
- iResult = shutdown(ClientSocket, SD_SEND);
- if(iResult == SOCKET_ERROR)
- {
- printf("server shutdown failed %ld\n", WSAGetLastError());
- closesocket(ClientSocket);
- WSACleanup();
- return 1;
- }
- closesocket(ClientSocket);
- WSACleanup();
-
- return 0;
- }
- /*client.cpp*/
-
- //prevent winsock.h (version 1.1)from being included by windows.h
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
- #include <Windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <iphlpapi.h> // after winsock2.h
- #include <cstdio>
-
- #pragma comment (lib, "Ws2_32.lib")
- #pragma comment (lib, "Mswsock.lib")
- #pragma comment (lib, "AdvApi32.lib")
-
- #define DEFAULT_PORT "27015"
- #define DEFAULT_BUFLEN 512
-
-
-
-
- int main ()
- {
- int iResult;
- WSADATA wsaData;
- struct addrinfo *result = NULL, *ptr = NULL, hints;
- char sendbuf[] = "this is a test for client";
- char recvbuf[DEFAULT_BUFLEN];
- int recvbuflen = DEFAULT_BUFLEN;
- char temp[DEFAULT_BUFLEN], file_name[DEFAULT_BUFLEN];
-
- printf("input ip address of server and file name\n");
- scanf("%s%s", temp, file_name);
-
- //create file
- FILE *fp = fopen(file_name, "wb");
- if(fp == NULL)
- {
- printf("create file %s failed\n", file_name);
- return -1;
- }
-
- // initialize
- if(WSAStartup(MAKEWORD(2,2), &wsaData))
- {
- printf("client WSAStartup failed: %d\n", iResult);
- return 1;
- }
-
- ZeroMemory(&hints, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
-
- // resolve the server address and port, argv[1] is server name
- iResult = getaddrinfo(temp, DEFAULT_PORT, &hints, &result);
- if(iResult != 0)
- {
- printf("client get addrinfor fail: %d\n", iResult);
- WSACleanup(); // terminate use of WS2_32.dll
- return 1;
- }
-
-
- SOCKET ConnectSocket = INVALID_SOCKET;
- for(ptr = result; ptr != NULL; ptr = ptr->ai_next)
- {
- // create a socket for client
- ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
- if(ConnectSocket == INVALID_SOCKET)
- {
- printf("client socket failed with error %ld\n", WSAGetLastError());
- WSACleanup();
- return 1;
- }
-
- // connect to server
- iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
- if(iResult == SOCKET_ERROR)
- {
- closesocket(ConnectSocket);
- ConnectSocket = INVALID_SOCKET;// if fail try next address returned by getaddrinfo
- continue;
- }
- break;
- }
-
-
- freeaddrinfo(result);
- if(ConnectSocket == INVALID_SOCKET)
- {
- printf("client unable to connect to server\n");
- WSACleanup();
- return 1;
- }
-
- //receive data from server
- int num = 0;
- while (1)
- {
- num = recv(ConnectSocket, temp, DEFAULT_BUFLEN, 0);
- if(num == 0)
- break;
- fwrite(temp, 1, num, fp);
- }
- printf("transmission done\n");
-
- fclose(fp);
- closesocket(ConnectSocket);
- WSACleanup();
-
- return 0;
- }
|