// Server.cpp : 定义控制台应用程序的入口点。
//是一个全双杠模式
#include "stdafx.h"
#include <stdio.h>
#include <Winsock2.h>
#define MAXLINE 50
///////////////////////////////////write n bytes to a descripture;
size_t writen(SOCKET m_socket, const void *vptr, size_t n)
{
size_t nleft;
size_t nwritten;
const char *ptr;
ptr = vptr;
nleft = n;
while (nleft> 0)
{
if (nwritten = write(m_socket)) <= 0
{
if (nwritten < 0 && errno == EINTR)
{
nwritten = 0;
}
else
{
return -1;
}
}
nleft -= nwritten;
ptr += nwritten
}
return n;
}
/////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
size_t readline(SOCKET m_socket, void *vptr, size_t maxlen)
{
size_t n, rc;
char c, *ptr;
ptr = vptr;
for(n = 1; n < maxlen; n++)
{
again:
if((rc = read(SOCKET)) == 1)
{
*prc++ = c;
if (c == '\n')
{
break;
}
}else if(rc == 0)
{
*ptr = 0;
return (n -1);
}else
{
if (errno == EINTR)
{
goto again;
return -1;
}
}
}
*ptr = 0;
return (n);
}
////////////////////////////////////创建新进程
int creage_proc(int argc, char* argv[])
{
//创建进程
wchar_t szCommandLine[] = _T("cmd");//调用命令行
STARTUPINFO si={sizeof(si)};
PROCESS_INFORMATION pi;
si.dwFlags=STARTF_USESHOWWINDOW;
si.wShowWindow=true;
bool bRet=::CreateProcess(
NULL,
szCommandLine,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi);
if(bRet)
{
::CloseHandle(pi.hThread);
::CloseHandle(pi.hProcess);
printf("新进程的进程ID号:%d\n",pi.dwProcessId);
printf("新进程的主线程的ID号:%d\n",pi.dwThreadId);
}
//system("pause");
return 0;
}
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////str_echo
void str_echo(SOCKET sock_conn)
{
int n;
char buf[MAXLINE];
again:
while((n = read(sock_conn,buf, MAXLINE)) > 0)
Writen(sock_conn, buf, n);
if(n < 0 && errno == EINTER)
goto again;
else if (n < 0)
printf("str_echo:read error");
}
//////////////////////////////////////////////////////////////
int _tmain(int argc, _TCHAR* argv[])
{
WORD wVersionRequested;
WSADATA wsaData; //获得winsocket初始化的值
int err;
wVersionRequested = MAKEWORD( 1, 1 );//socket版本号
err = WSAStartup( wVersionRequested, &wsaData );//WSAStartup,是Windows Sockets Asynchronous的启动命令、Windows下的网络编程接口软件 Winsock1 或 Winsock2 里面的一个命令。
if ( err != 0 ) { //为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化,
return -1;
}
if ( LOBYTE( wsaData.wVersion ) != 1 || //LOWORD()得到一个32bit数的低16bit LOBYTE()得到一个16bit数最低(最右边)那个字节
HIBYTE( wsaData.wVersion ) != 1 ) { //HIWORD()得到一个32bit数的高16bit, 不是前面所说的版本号
WSACleanup( );
return -1;
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv; //socket绑定的IP地址
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //将主机数转换成无符号长整型的网络字节顺序。本函数将一个32位数从主机字节顺序转换成网络字节顺序。
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);//端口
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));// 绑定端口 SOCKADDR包含端口struct sockaddr // unsigned short sa_family; /* address family, AF_xxx */ // char sa_data[14]; /* 14 bytes of protocol address */
listen(sockSrv, 5); //监听
SOCKADDR_IN addrClient;// 连接上的客户端ip地址
for ( ; ;) //在accept部分循环
{
int len=sizeof(SOCKADDR_IN);//客户端地址的长度
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);// 接受客户端连接,获取客户端的ip地址
if(creage_proc(int argc, char* argv[]) == 0) //创建新进程成功
{
closesocket(sockSrv);
str_echo(sockConn);
exit(0);
}
close(sockConn)
}
}
char sendBuf[50];
sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));// 组合消息发送出去
send(sockConn,sendBuf,strlen(sendBuf)+1,0);// 发送消息到客户端
char recvBuf[50];
recv(sockConn,recvBuf,50,0);// 接受客户端消息
/* if(recvBuf == "hello")
{
send(sockConn, "你好", sizeof("你好"), 0);
}*/
/* printf("%s\n",recvBuf);*/
closesocket(sockConn);//断开连接
}
system("pause");
}
04-03