学了Windows下的网路编程,做了一个小例子试了下手,和Linux下的网路编程感觉总体上差不多,但是细节上,比如说函数的实现还是有些不同。总的结构和Linux差不多,如下图所示:
话不多说,直接上代码,和Linux网络编程一样,我也把socket、bind、listen、accept、connect函数封装在了一个文件中,服务器和客户端是公用的。
/***********socket.h********************/
#ifndef SOCKET_H
#define SOCKET_H
#pragma comment(lib, "ws2_32.lib")
#include <iostream>
#include <string>
#include <Windows.h>
#define SERV_PORT 9000
using namespace std;
extern void tcp_WSA();
extern int tcp_init();
extern int tcp_accept(int sfd);
extern int tcp_connet();
#endif
/***********socket.c********************/
#include "socket.h"
void tcp_WSA()
{
WSADATA lpWSAD;
WORD wVer = MAKEWORD(2,2);
int ret;
ret = WSAStartup(wVer, &lpWSAD);
if (ret != 0)
{
cout<<"初始化错误"<<endl;
return; //初始化错误
}
if ( LOBYTE( lpWSAD.wVersion ) != 2 || HIBYTE( lpWSAD.wVersion ) != 2 )
{
cout<<WSACleanup( )<<endl;
return;
}
}
int tcp_init()
{
SOCKET sfd;
sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sfd == INVALID_SOCKET)
{
cout<<"socket create fail"<<endl;
return -1;
}
int ret;
struct sockaddr_in FAR serveraddr;
memset(&serveraddr,0,sizeof(struct sockaddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERV_PORT);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
ret = bind(sfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr));
if (ret == SOCKET_ERROR)
{
cout<<"bind fail"<<endl;
return -1;
}
ret = listen(sfd, 10);
if (ret == SOCKET_ERROR)
{
cout<<"listen fail"<<endl;
return -1;
}
return sfd;
}
int tcp_accept(int sfd)
{
SOCKET cfd;
struct sockaddr_in FAR addr;
int FAR addrlen = sizeof(struct sockaddr);
cfd = accept(sfd, (struct sockaddr *)&addr, &addrlen);
if (cfd == INVALID_SOCKET)
{
cout<<"accept fail"<<endl;
return -1;
}
cout<<inet_ntoa(addr.sin_addr)<<" "<<ntohs(addr.sin_port)<<" success connect..."<<endl;
return cfd;
}
int tcp_connet()
{
int ret;
SOCKET sfd;
sfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sfd == INVALID_SOCKET)
{
cout<<"socket create fail"<<endl;
return -1;
}
struct sockaddr_in FAR serveraddr;
memset(&serveraddr, 0,sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(SERV_PORT);
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = connect(sfd, (struct sockaddr*)&serveraddr, sizeof(struct sockaddr)); //将sfd连接至指定的服务器网络地址 serveraddr
if (ret == SOCKET_ERROR)
{
cout<<"connect fail"<<endl;
return -1;
}
return sfd;
}
/***********client.c********************/
#include "socket.h"
int main()
{
tcp_WSA();
int sfd, ret;
char ch;
sfd = tcp_connet();
while(1)
{
cout<<"请输入一个小写字母:";
cin>>ch;
ret = send(sfd, &ch, sizeof(ch), 0);
if (ret == -1)
{
cerr<<"send error,please send again"<<endl;
continue;
}
ret = recv(sfd, &ch, sizeof(ch), 0);
if(ret == -1)
{
cerr<<"recv error"<<endl;
continue;
}
cout<<"转换后的字母为:"<<ch<<endl;
}
shutdown(sfd, 2);
closesocket(sfd);
WSACleanup();
}
/**************server.c******************/
#include "socket.h"
DWORD WINAPI func(LPVOID p)
{
int cfd = (int)p;
int ret;
char ch;
while(1)
{
ret = recv(cfd, &ch, sizeof(ch), 0);
if(ret == -1)
{
cerr<<"xxx下线"<<endl;
break;
}
ch = ch - ('a' - 'A');
ret = send(cfd, &ch, sizeof(ch), 0);
if(ret == -1)
{
cerr<<"send error"<<endl;
continue;
}
}
return 0;
}
int main()
{
int ret;
SOCKET sfd, cfd;
tcp_WSA();
sfd = tcp_init();
while (1)
{
cfd = tcp_accept(sfd);
DWORD thread1Id;
HANDLE handel1 = CreateThread(NULL, 0, func, (LPVOID) cfd, 0, &thread1Id);
if (handel1 == false)
{
cerr<<"create error"<<endl;
return -1;
}
WaitForSingleObject(handel1, 0);
CloseHandle(handel1);
}
shutdown(cfd, 2);
closesocket(cfd);
WSACleanup();
}