// Windows_TCP_socket_Sever.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<WINSOCK2.H>
#pragma comment (lib,"Ws2_32.lib")
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
//初始化Ws2_32.lib
WSADATA data;
if(WSAStartup(MAKEWORD(2,2),&data)!=0)
{
cout<<"WSAStartup无法初始化"<<endl;
return 0;
}
//cout<<"version:"<<LOBYTE(data.wVersion)<<"."<<HIBYTE(data.wVersion)<<endl;
printf("version:%d.%d\n",LOBYTE(data.wVersion),HIBYTE(data.wVersion)); //c++输出10进制?
//cout<<"High Version:"<<dec<<LOBYTE(data.wHighVersion)<<"."<<HIBYTE(data.wHighVersion)<<endl;
printf("version:%d.%d\n",LOBYTE(data.wHighVersion),HIBYTE(data.wHighVersion));
cout<<"Description:"<<data.szDescription<<endl;
cout<<"System Status:"<<data.szSystemStatus<<endl;
//创建监听套接字
SOCKET ListenSocket;
ListenSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(ListenSocket==INVALID_SOCKET)
{
cout<<"Socket error!"<<endl;
WSACleanup();
return -1;
}
//创建套接字地址结构,绑定
SOCKADDR_IN Saddr;
Saddr.sin_family=AF_INET;
Saddr.sin_port=htons(1020);
Saddr.sin_addr.s_addr=htons(INADDR_ANY);
//sin_addr是IP地址结构体in_addr的结构对象,s_addr是sin_addr的结构成员,存放32位IP地址
int errcode=bind(ListenSocket,(sockaddr*)&Saddr,sizeof(SOCKADDR_IN));
//(sockaddr*)&saClient强制类型转化,从sockaddr_in类型转换成sockaddr类型。winsock API中使用sockaddr类,程序中使用sockaddr_in类
if(errcode==SOCKET_ERROR)
{
cout<<"bind failed!"<<endl;
closesocket(ListenSocket);
WSACleanup();
return -1;
}
//在套接字上监听
int value=listen(ListenSocket,5);
if(value==SOCKET_ERROR)
{
cout<<"listen error!"<<endl;
closesocket(ListenSocket);
WSACleanup();
return -1;
}
cout<<"TCP Server start...\r"<<endl;
//创建客户端套接字与地址结构
SOCKET ClientSocket;
SOCKADDR_IN Clientaddr;
int len=sizeof(Clientaddr);
ClientSocket=accept(ListenSocket,(sockaddr FAR*)&Clientaddr,&len);
//1.监听套接字 2.新的地址结构对象存放客户端套接字地址 3.客户端对象长度
if(ClientSocket!=INVALID_SOCKET)
{ //accept成功,返回一个新的套接字句柄,否则返回>>>INVALID_SOCKET<<<.WSAGetLastError函数可以获取错误代码,第一个参数是监听套接字
cout<<inet_ntoa(Clientaddr.sin_addr)<<"已经连接上\r\n"<<endl;
}
else
cout<<"accept:"<<WSAGetLastError()<<endl;
char sendbuf[]="hello,you have already connected.\r";
send(ClientSocket,sendbuf,sizeof(sendbuf),0);
//SO_MAX_MSG_SIZE可以用来获取系统允许的最大字符串长度
while(true)
{
char recvbuf[100];
errcode=recv(ClientSocket,recvbuf,100,0);
if(errcode==0)
cout<<"The connection has closed.\n";
else if(errcode==SOCKET_ERROR)
cout<<WSAGetLastError()<<endl;
else
{
cout<<"Client said: "<<recvbuf<<endl;
if(strcmp(recvbuf,"quit")==0)
break;
}
}
//关闭套接字,释放资源
closesocket(ClientSocket);
closesocket(ListenSocket);
if(WSACleanup()==SOCKET_ERROR)
cout<<"WSACleanup error!"<<endl;
if(getchar())
return 0;
}
TCP服务器端实现步骤:
1.建立监听套接字,返回套接字句柄
2.建立本地套接字地址结构,与套接字绑定bind()
3.监听套接字监听端口listen()
4.等待客户端连接请求accept(),建立连接,得到连接套接字
5.在套接字上读写数据send(),recv()等
6.关闭连接套接字与监听套接字
// Windows_TCP_client.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<WINSOCK2.H>
#pragma comment (lib,"Ws2_32.lib")
using namespace std;
#define BUF_SIZE 64
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsd;
SOCKET client;
if(WSAStartup(MAKEWORD(2,2),&wsd)!=0) //执行成功返回0
{
cout<<"WSAStartup failed!\n";
//return -1;
}
/***************************************************************************************
* client=(AF_INET,SOCK_STREAM,IPPROTO_TCP); 少了socket函数名,所以运行出现问题 *
***************************************************************************************/
client=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//设置服务器地址
SOCKADDR_IN saddr;
saddr.sin_family=AF_INET;
saddr.sin_port=htons(1020);
saddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
int len=sizeof(saddr);
//连接服务器
int value=connect(client,(sockaddr*)&saddr,len);
if(value==INVALID_SOCKET)
{
cout<<"connect failed!"<<endl;
closesocket(client);
WSACleanup();
return -1;
}
char recvbuf[BUF_SIZE];
value=recv(client,recvbuf,BUF_SIZE,0);
cout<<"Server:"<<recvbuf<<endl;
while(true)
{
cout<<"please input a string to send:\n";
char sendbuf[BUF_SIZE];
cin>>sendbuf;
int value=send(client,sendbuf,BUF_SIZE,0);
if(value==SOCKET_ERROR)
{
cout<<"send failed!"<<endl;
closesocket(client);
WSACleanup();
//return -1;
}
}
closesocket(client);
WSACleanup();
if(getchar())
return 0;
}
TCP客户端实现
1.建立连接套接字,返回句柄
2.将套接字与远程主机相连connect()
3.与客户端通信recv(),send()
4.关闭套接字