网络编程之路---8
2014-02-23 15:55
441 查看
设置非阻塞式socket
int ioctlsocket(SOCKET s, long cmd, u_long* argp);
socket句柄 在sockets上面执行的命令 指定cmd命令的参数
服务端(非阻塞):
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <stdio.h>
#define BUF_SIZE 64 //定义缓冲区的大小
int main(int argc, char *argv[])
{
WSADATA wsaData; //WSA windows socket api
char buf[BUF_SIZE]; //缓冲区
int resValue; //用来接收函数的返回值
if ((WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
//用于初始化windows sockets并返回WSADATA结构体
{
//MessageBox(NULL, L"无法初始化", L"WindowsApi", 0);
printf("无法初始化!");
return 0;
}
//...
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //创建tcp套接字(服务器)
//地址家族, 套接字类型,套接字使用的协议
if (s == INVALID_SOCKET)
{
printf("socket error!");
}
int iMode = 1;
resValue = ioctlsocket(s, FIONBIO, (u_long FAR*)&iMode); //将该socket设置为非阻塞式的
if (resValue == SOCKET_ERROR)
{
printf("ioctlsocket failed\n");
closesocket(s);
WSACleanup();
return -1;
}
SOCKADDR_IN addr; //命名socket,服务器地址
//struct sockaddr_in addr; //命名socket,地址
addr.sin_family = AF_INET; //因特网地址家族或协议系列
addr.sin_port = htons(9990); //主机->网络
addr.sin_addr.S_un.S_addr =/*inet_addr("222.18.167.206")*//*htonl(INADDR_ANY)*/inet_addr("222.18.167.240"); //在任意本地地址上进行监听
int errorCode; //错误代码
int addr_len = sizeof(struct sockaddr_in);
errorCode = bind(s, (const SOCKADDR*)&addr, addr_len);
//未绑定的套接字描述符 命名socket的地址 地址长度
if (errorCode == SOCKET_ERROR)
{
printf("bind error!");
closesocket(s);
exit(1);
}
//截止到现在socket的全部属性已经被填充,客户端可以定位到服务器socket
errorCode = listen(s, 3);
if (errorCode == SOCKET_ERROR)
{
printf("listen error");
closesocket(s); //关闭套接字
exit(2);
}
//服务端的socket已经准备好...
//现在开始客户端的socket
printf("TCP SERVER start...\n");
SOCKET sockAccept; //执行accept函数后用于实际通信的套接字
SOCKADDR_IN ClientAddr; //客户端地址
int len = sizeof(ClientAddr);
while (true)
{
sockAccept = accept(s, (SOCKADDR*)&ClientAddr, &len);
if (sockAccept == INVALID_SOCKET) //为非阻塞式的,所以socket不一定就是有效的
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(100);
continue;
}
else
{
printf("accept failed\n");
closesocket(s);
closesocket(sockAccept);
WSACleanup();
return -1;
}
}
break;
}
//循环接收来自客户端的数据
while (true)
{
ZeroMemory(buf, BUF_SIZE); //每次清空缓冲
resValue = recv(sockAccept, buf, BUF_SIZE, 0); //接收来自客户端的数据 现在是非阻塞式的
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(500);
continue;
}
else if(err == WSAETIMEDOUT || err == WSAENETDOWN) //超时 或者网络关闭
{
printf("recv failed!");
closesocket(s);
closesocket(sockAccept);
WSACleanup();
return -1;
}
}
SYSTEMTIME st;
GetLocalTime(&st);
char sDataTime[30];
sprintf(sDataTime, "%4d-%2d-%2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,st.wMinute, st.wSecond);
printf("%s, Recv From Client [%s:%d] :%s\n", sDataTime, inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf);
if (strcmp(buf, "quit") == 0)
{
resValue = send(sockAccept, "quit", strlen("quit"), 0); //发往客户端的数据
break;
}
//向客户端发送回显字符
else
{
char msg[BUF_SIZE];
sprintf(msg, "Message Received - %s", buf);
resValue = send(sockAccept, buf, BUF_SIZE, 0);
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(500);
continue;
}
else
{
printf("Socket send Failed\n");
closesocket(s);
closesocket(sockAccept);
WSACleanup();
return -1;
}
}
//break;
}
}
closesocket(s);
closesocket(sockAccept);
if ((WSACleanup() == SOCKET_ERROR))
{
MessageBox(NULL, L"清除失败", L"WindowsApi", 0);
return 0;
}
system("pause");
return 0;
}
客户端(非阻塞)
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <stdio.h>
#include <iostream>
#include <string>
#define BUF_SIZE 64 //定义缓冲区的大小
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET sHost; //创建客户端的socket
int resValue; //函数返回值,用于查看函数执行情况
char buf[BUF_SIZE]; //缓冲区
if ((WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
//用于初始化windows sockets并返回WSADATA结构体
{
//MessageBox(NULL, L"无法初始化", L"WindowsApi", 0);
printf("无法初始化!");
return 0;
}
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sHost == INVALID_SOCKET)
{
printf("socket failed! \n");
WSACleanup();
return -1;
}
int iMode = 1; //设置为非阻塞模式
resValue = ioctlsocket(sHost, FIONBIO, (u_long FAR*)&iMode);
if (resValue == SOCKET_ERROR)
{
printf("ioctlsocket error\n");
closesocket(sHost);
WSACleanup();
return -1;
}
SOCKADDR_IN servAddr; //服务器的地址,端口号
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr("222.18.167.240");
servAddr.sin_port = htons(9990);
int sServerAddlen = sizeof(servAddr); //服务器地址长度
while (true)
{
resValue = connect(sHost, (const SOCKADDR*)&servAddr, sServerAddlen);
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) //非阻塞 还未有socket连接
{
Sleep(500);
continue;
}
else if (err == WSAEISCONN) //已经建立连接 WSAEWOULDBLOCK WSAEINVAL监听 WSAEISCONN 如果第一次成功就会直接进入
{
break;
}
else
{
printf("connect failed\n");
closesocket(sHost);
WSACleanup();
return -1;
}
}
}
while (true)
{
printf("\nplease input a string to send\n");
std::string str;
std::getline(std::cin, str); //接收输入的数据
ZeroMemory(buf,BUF_SIZE);
strcpy(buf, str.c_str()); //将用户的输入复制到buf里面
while (true)
{
resValue = send(sHost, buf, strlen(buf), 0);
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(500);
continue;
}
else {
printf("socket send failed!\n");
closesocket(sHost);
WSACleanup();
return -1;
}
}
break;
}
while (true)
{
ZeroMemory(buf,BUF_SIZE);
resValue = recv(sHost, buf, sizeof(buf) + 1, 0);
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(500);
continue;
}
else if(err == WSAETIMEDOUT || err == WSAENETDOWN)
{
printf("recv failed\n");
closesocket(sHost);
WSACleanup();
return -1;
}
break;
}
break;
}
// resValue = recv(sHost, buf, sizeof(buf) + 1, 0);
// //要接收数据的socket 要接收数据buf的地址 要接收数据buf的长度 0
// if (resValue == SOCKET_ERROR)
// {
// printf("socket receive failed!\n");
// closesocket(sHost);
// WSACleanup();
// return -1;
// }
printf("Receive from server: %s", buf);
if (strcmp(buf, "quit") == 0)
{
printf("quit");
break;
}
}
closesocket(sHost);
WSACleanup();
system("pause");
return 0;
}
int ioctlsocket(SOCKET s, long cmd, u_long* argp);
socket句柄 在sockets上面执行的命令 指定cmd命令的参数
服务端(非阻塞):
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <stdio.h>
#define BUF_SIZE 64 //定义缓冲区的大小
int main(int argc, char *argv[])
{
WSADATA wsaData; //WSA windows socket api
char buf[BUF_SIZE]; //缓冲区
int resValue; //用来接收函数的返回值
if ((WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
//用于初始化windows sockets并返回WSADATA结构体
{
//MessageBox(NULL, L"无法初始化", L"WindowsApi", 0);
printf("无法初始化!");
return 0;
}
//...
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //创建tcp套接字(服务器)
//地址家族, 套接字类型,套接字使用的协议
if (s == INVALID_SOCKET)
{
printf("socket error!");
}
int iMode = 1;
resValue = ioctlsocket(s, FIONBIO, (u_long FAR*)&iMode); //将该socket设置为非阻塞式的
if (resValue == SOCKET_ERROR)
{
printf("ioctlsocket failed\n");
closesocket(s);
WSACleanup();
return -1;
}
SOCKADDR_IN addr; //命名socket,服务器地址
//struct sockaddr_in addr; //命名socket,地址
addr.sin_family = AF_INET; //因特网地址家族或协议系列
addr.sin_port = htons(9990); //主机->网络
addr.sin_addr.S_un.S_addr =/*inet_addr("222.18.167.206")*//*htonl(INADDR_ANY)*/inet_addr("222.18.167.240"); //在任意本地地址上进行监听
int errorCode; //错误代码
int addr_len = sizeof(struct sockaddr_in);
errorCode = bind(s, (const SOCKADDR*)&addr, addr_len);
//未绑定的套接字描述符 命名socket的地址 地址长度
if (errorCode == SOCKET_ERROR)
{
printf("bind error!");
closesocket(s);
exit(1);
}
//截止到现在socket的全部属性已经被填充,客户端可以定位到服务器socket
errorCode = listen(s, 3);
if (errorCode == SOCKET_ERROR)
{
printf("listen error");
closesocket(s); //关闭套接字
exit(2);
}
//服务端的socket已经准备好...
//现在开始客户端的socket
printf("TCP SERVER start...\n");
SOCKET sockAccept; //执行accept函数后用于实际通信的套接字
SOCKADDR_IN ClientAddr; //客户端地址
int len = sizeof(ClientAddr);
while (true)
{
sockAccept = accept(s, (SOCKADDR*)&ClientAddr, &len);
if (sockAccept == INVALID_SOCKET) //为非阻塞式的,所以socket不一定就是有效的
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(100);
continue;
}
else
{
printf("accept failed\n");
closesocket(s);
closesocket(sockAccept);
WSACleanup();
return -1;
}
}
break;
}
//循环接收来自客户端的数据
while (true)
{
ZeroMemory(buf, BUF_SIZE); //每次清空缓冲
resValue = recv(sockAccept, buf, BUF_SIZE, 0); //接收来自客户端的数据 现在是非阻塞式的
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(500);
continue;
}
else if(err == WSAETIMEDOUT || err == WSAENETDOWN) //超时 或者网络关闭
{
printf("recv failed!");
closesocket(s);
closesocket(sockAccept);
WSACleanup();
return -1;
}
}
SYSTEMTIME st;
GetLocalTime(&st);
char sDataTime[30];
sprintf(sDataTime, "%4d-%2d-%2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute,st.wMinute, st.wSecond);
printf("%s, Recv From Client [%s:%d] :%s\n", sDataTime, inet_ntoa(ClientAddr.sin_addr), ClientAddr.sin_port, buf);
if (strcmp(buf, "quit") == 0)
{
resValue = send(sockAccept, "quit", strlen("quit"), 0); //发往客户端的数据
break;
}
//向客户端发送回显字符
else
{
char msg[BUF_SIZE];
sprintf(msg, "Message Received - %s", buf);
resValue = send(sockAccept, buf, BUF_SIZE, 0);
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(500);
continue;
}
else
{
printf("Socket send Failed\n");
closesocket(s);
closesocket(sockAccept);
WSACleanup();
return -1;
}
}
//break;
}
}
closesocket(s);
closesocket(sockAccept);
if ((WSACleanup() == SOCKET_ERROR))
{
MessageBox(NULL, L"清除失败", L"WindowsApi", 0);
return 0;
}
system("pause");
return 0;
}
客户端(非阻塞)
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#include <stdio.h>
#include <iostream>
#include <string>
#define BUF_SIZE 64 //定义缓冲区的大小
int main(int argc, char *argv[])
{
WSADATA wsaData;
SOCKET sHost; //创建客户端的socket
int resValue; //函数返回值,用于查看函数执行情况
char buf[BUF_SIZE]; //缓冲区
if ((WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
//用于初始化windows sockets并返回WSADATA结构体
{
//MessageBox(NULL, L"无法初始化", L"WindowsApi", 0);
printf("无法初始化!");
return 0;
}
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sHost == INVALID_SOCKET)
{
printf("socket failed! \n");
WSACleanup();
return -1;
}
int iMode = 1; //设置为非阻塞模式
resValue = ioctlsocket(sHost, FIONBIO, (u_long FAR*)&iMode);
if (resValue == SOCKET_ERROR)
{
printf("ioctlsocket error\n");
closesocket(sHost);
WSACleanup();
return -1;
}
SOCKADDR_IN servAddr; //服务器的地址,端口号
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr("222.18.167.240");
servAddr.sin_port = htons(9990);
int sServerAddlen = sizeof(servAddr); //服务器地址长度
while (true)
{
resValue = connect(sHost, (const SOCKADDR*)&servAddr, sServerAddlen);
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK) //非阻塞 还未有socket连接
{
Sleep(500);
continue;
}
else if (err == WSAEISCONN) //已经建立连接 WSAEWOULDBLOCK WSAEINVAL监听 WSAEISCONN 如果第一次成功就会直接进入
{
break;
}
else
{
printf("connect failed\n");
closesocket(sHost);
WSACleanup();
return -1;
}
}
}
while (true)
{
printf("\nplease input a string to send\n");
std::string str;
std::getline(std::cin, str); //接收输入的数据
ZeroMemory(buf,BUF_SIZE);
strcpy(buf, str.c_str()); //将用户的输入复制到buf里面
while (true)
{
resValue = send(sHost, buf, strlen(buf), 0);
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(500);
continue;
}
else {
printf("socket send failed!\n");
closesocket(sHost);
WSACleanup();
return -1;
}
}
break;
}
while (true)
{
ZeroMemory(buf,BUF_SIZE);
resValue = recv(sHost, buf, sizeof(buf) + 1, 0);
if (resValue == SOCKET_ERROR)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
Sleep(500);
continue;
}
else if(err == WSAETIMEDOUT || err == WSAENETDOWN)
{
printf("recv failed\n");
closesocket(sHost);
WSACleanup();
return -1;
}
break;
}
break;
}
// resValue = recv(sHost, buf, sizeof(buf) + 1, 0);
// //要接收数据的socket 要接收数据buf的地址 要接收数据buf的长度 0
// if (resValue == SOCKET_ERROR)
// {
// printf("socket receive failed!\n");
// closesocket(sHost);
// WSACleanup();
// return -1;
// }
printf("Receive from server: %s", buf);
if (strcmp(buf, "quit") == 0)
{
printf("quit");
break;
}
}
closesocket(sHost);
WSACleanup();
system("pause");
return 0;
}
相关文章推荐
- 网络编程之路---10
- 网络编程之路---4
- 网络编程之路---7
- 网络编程之路---5
- 网络编程之路---11
- java网络编程之路(一)
- 网络编程之路---12
- 网络编程之路---9
- 网络编程之路---3
- 网络编程之路---6
- 网络编程之路(第一天)
- 菜鸟的网络编程之路(一) —— Socket的理解
- 网络涂鸦时代
- 什么是Google即时通话工具-即时聊天工具网络接口比较
- 转准备网络工程师该看哪些书
- Windows server 2003下实战利用MRTG进行网络监控(一)
- ProjectWise 工程内容管理及协同工作解决方案系列网络讲座
- 网络编程常见问题总结 串讲
- InfiniBand 网络
- 僵尸网络用SSL链接攻击主要互联网网站