1、API详解
(1)int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData)
为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化。该函数的第一个参数指明程序请求使用的Socket版本,操作系统利用第二个参数返回请求的Socket的版本信息。当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。
(2)socket()
根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源。
(3)bind()
将一本地地址与一套接口捆绑。
(4)listen()
创建一个套接口并监听申请的连接。
(5)accept()
在一个套接口接受一个连接。成功返回一个新的套接字描述符。
(6)recv()
从一个套接口接收数据。
(7)send()
(1)int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData)
为了在应用程序当中调用任何一个Winsock API函数,首先第一件事情就是必须通过WSAStartup函数完成对Winsock服务的初始化。该函数的第一个参数指明程序请求使用的Socket版本,操作系统利用第二个参数返回请求的Socket的版本信息。当一个应用程序调用WSAStartup函数时,操作系统根据请求的Socket版本来搜索相应的Socket库,然后绑定找到的Socket库到该应用程序中。
(2)socket()
根据指定的地址族、数据类型和协议来分配一个套接口的描述字及其所用的资源。
(3)bind()
将一本地地址与一套接口捆绑。
(4)listen()
创建一个套接口并监听申请的连接。
(5)accept()
在一个套接口接受一个连接。成功返回一个新的套接字描述符。
(6)recv()
从一个套接口接收数据。
(7)send()
向一个已经连接的socket发送数据
2、源码
服务端:
#include <stdio.h>
#include <winsock2.h> //winsock.h (2种套接字版本)
#include <process.h> //for beginthread
#pragma comment(lib,"ws2_32.lib") //wsock32.lib
#define MAX_LISTEN_NUM 5 //最多可同时监听的客户连接数
#define CONNECT_PORT 1027
#define CONNECT_IP "127.0.0.1"
#define DEFAULT_BUFF_SIZE 512
unsigned int WINAPI ClientThread(void* lpParam)
{
//当前线程中保存指定的客户端Socket
SOCKET sClient = (SOCKET)lpParam;
char szBuff[DEFAULT_BUFF_SIZE] ={0};
int nRes;
int nLeft; //剩余字节数,用于发送
int nIndex; //送信Buff下标
printf("******Start a Client: ThreadID=%d, Socket=%d******\n",::GetCurrentThreadId(),sClient);
while(true)
{
printf("--- start recv message(ThreadID:%d)\n",::GetCurrentThreadId());
memset(szBuff, 0, sizeof(szBuff) );
nRes = recv(sClient, szBuff, sizeof(szBuff), 0); //这里会阻塞
//当拔掉设备网线的时候,recv并不会发生变化,仍然阻塞,如果在这个拔网线阶段,socket被关掉了,后果可能就是recv永久的阻塞了。
if( nRes == 0 ) //socket被正常关闭时,返回0。
{
printf("-XXX Client Has Closed.\n");
break;
}
else if(nRes == SOCKET_ERROR )
{
printf("-XXX ClientThread recv Failed: %d\n",WSAGetLastError());
break;
}
//获取到了指定的字节数
szBuff[nRes] = '\0';
printf("-recved message(ThreadID:%d):(%d): %s\n",::GetCurrentThreadId(),nRes,szBuff);
//告诉客户端收到了发送的数据
printf("-send message:(%d): %s\n",nRes,szBuff);
nLeft = nRes; //指示收到了多少字节
nIndex = 0;
while( nLeft>0 )
{
nRes = send(sClient, &szBuff[nIndex], nLeft, 0);
if( nRes == 0 )
{
printf("-send message OK\n");
break;
}
else if( nRes == SOCKET_ERROR )
{
printf("-XXX ClientThread send Failed: %d\n",WSAGetLastError());
break;
}
nLeft -= nRes;
nIndex += nRes;
}//while(nLeft>0)
}//while(true)
printf("******Close a Client******\n");
return 0;
}
int main()
{
WSAData wsdata;
SOCKET sockServer;
SOCKET sockRecvClient;
SOCKADDR_IN addrServer;
SOCKADDR_IN addrRecvClient;
int addrlenClient;
HANDLE hThread; //处理客户连接用的线程Handle
UINT nThreadID;
int nError = -1;
printf(">>>>>>>>server