#include "stdafx.h"
#include <WinSock2.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("client: input ip address of server and file name\n");
scanf("%s%s", temp, file_name);
//create file
FILE *fp = fopen(file_name, "wb");//'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清零
hints.ai_family = AF_UNSPEC; //函数返回的是适用于指定主机名和服务名且适合任何协议族的地址
hints.ai_socktype = SOCK_STREAM; //TCP协议
hints.ai_protocol = IPPROTO_TCP; //绑定主叫
// resolve the server address and port, argv[1] is server name
iResult = getaddrinfo(temp, DEFAULT_PORT, &hints, &result);//temp:IP地址 完成主机名到地址解析
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(true){
while (1)
{
//ConnectSocket:套接字描述符 temp:数据copy到此缓冲区
num = recv(ConnectSocket, temp, DEFAULT_BUFLEN, 0); //http://blog.csdn.net/tiandyoin/article/details/30044781
if(num == 0) //recv<0:出错 recv=0:连接关闭 recv>0:接收到数据大小
break;
fwrite(temp, 1, num, fp);
}
printf("transmission done\n");
fclose(fp);
closesocket(ConnectSocket);
WSACleanup(); // 终止Winsock 2 DLL (Ws2_32.dll) 的使用
return 0;
}
server:
#include "stdafx.h"
#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);//用于向一个已经连接的socket发送数据,如果无错误,返回值为所发送数据的总数
}
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;
}
第二种:
// sever.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
// Server.cpp : Defines the entry point for the console application.
#include "winsock2.h"
#pragma comment(lib, "ws2_32.lib")
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
const int BUF_SIZE = 64;
WSADATA wsd; //WSADATA变量
SOCKET sServer; //服务器套接字
SOCKET sClient; //客户端套接字
SOCKADDR_IN addrServ;; //服务器地址
char buf[BUF_SIZE]; //接收数据缓冲区
char sendBuf[BUF_SIZE];//返回给客户端得数据
int retVal; //返回值
//初始化套结字动态库
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
cout << "WSAStartup failed!" << endl;
return 1;
}
//创建套接字
sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == sServer)
{
cout << "socket failed!" << endl;
WSACleanup();//释放套接字资源;
return -1;
}
//服务器套接字地址
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(4999);
addrServ.sin_addr.s_addr = INADDR_ANY;
//绑定套接字
retVal = bind(sServer, (LPSOCKADDR)&addrServ, sizeof(SOCKADDR_IN));
if(SOCKET_ERROR == retVal)
{
cout << "bind failed!" << endl;
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
return -1;
}
//开始监听
retVal = listen(sServer, 1);
if(SOCKET_ERROR == retVal)
{
cout << "listen failed!" << endl;
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
return -1;
}
//接受客户端请求
sockaddr_in addrClient;
int addrClientlen = sizeof(addrClient);
sClient = accept(sServer,(sockaddr FAR*)&addrClient, &addrClientlen);
if(INVALID_SOCKET == sClient)
{
cout << "accept failed!" << endl;
closesocket(sServer); //关闭套接字
WSACleanup(); //释放套接字资源;
return -1;
}
while(true)
{
ZeroMemory(buf, BUF_SIZE);
retVal = recv(sClient, buf, BUF_SIZE, 0); //接收客户端数据
if (SOCKET_ERROR == retVal)
{
cout << "recv failed!" << endl;
closesocket(sServer); //关闭套接字
closesocket(sClient); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
}
if(buf[0] == '0')
break;
cout << "Server:客户端发送的数据: " << buf <<endl;
cout << "Server:向客户端发送数据: " ;
cin >> sendBuf;
send(sClient, sendBuf, strlen(sendBuf), 0);//向客户端发送数据
}
//退出
closesocket(sServer); //关闭套接字
closesocket(sClient); //关闭套接字
WSACleanup(); //释放套接字资源;
return 0;
}
client:
// My_TCP4.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "winsock2.h"
#include <iostream>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
BOOL RecvLine(SOCKET s, char* buf); //读取一行数据
int main(int argc, char* argv[])
{
const int BUF_SIZE = 64;
WSADATA wsd; //WSADATA变量
SOCKET sHost; //服务器套接字
SOCKADDR_IN servAddr; //服务器地址
char buf[BUF_SIZE]; //接收数据缓冲区
char bufRecv[BUF_SIZE];
int retVal; //返回值
//初始化套结字动态库
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
{
cout << "WSAStartup failed!" << endl;
return -1;
}
//创建套接字
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);cout<<"sHost:"<<sHost<<endl;
if(INVALID_SOCKET == sHost)
{
cout << "socket failed!" << endl;
WSACleanup();//释放套接字资源
return -1;
}
//设置服务器地址和端口
servAddr.sin_family =AF_INET;
servAddr.sin_addr.s_addr = inet_addr("127.0.0.21");
servAddr.sin_port = htons((short)4999);
int nServAddlen = sizeof(servAddr);
//连接服务器
retVal=connect(sHost,(LPSOCKADDR)&servAddr, sizeof(servAddr));
if(SOCKET_ERROR == retVal)
{
cout << "connect failed!" << endl;
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
}
while(true)
{
//向服务器发送数据
ZeroMemory(buf, BUF_SIZE);
cout << " 向服务器发送数据: ";
cin >> buf;
retVal = send(sHost, buf, strlen(buf), 0);
if (SOCKET_ERROR == retVal)
{
cout << "send failed!" << endl;
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
}
//RecvLine(sHost, bufRecv);
ZeroMemory(bufRecv, BUF_SIZE);
recv(sHost, bufRecv,BUF_SIZE , 0); // 接收服务器端的数据, 只接收5个字符
cout << endl <<"Client:从服务器接收数据:"<< bufRecv;
cout<<"\n";
}
//退出
closesocket(sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return 0;
}