点击查看代码

实现简单的Socket通信 服务端代码(Server) #include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define PORT 9999 int main()
{
WSADATA WSAData;
SOCKET sock, msgsock;
struct sockaddr_in ServerAddr; if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR)
{
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(PORT);
ServerAddr.sin_addr.s_addr = INADDR_ANY; sock = socket(AF_INET, SOCK_STREAM, 0);
int BindRet = bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));
int LinsRet = listen(sock, 10);
printf("------------------------------------------------------------------------------------------\n");
printf("绑定状态: %d\t 侦听状态: %d\t 绑定端口: %d\n", BindRet, LinsRet, ntohs(ServerAddr.sin_port));
printf("------------------------------------------------------------------------------------------\n");
} while (1)
{
char buf[1024];
msgsock = accept(sock, (LPSOCKADDR)0, (int *)0);
memset(buf, 0, sizeof(buf));
recv(msgsock, buf, 1024, 0);
printf("客户IP: %s\t 端口:%d\t 数据:%s\n", inet_ntoa(ServerAddr.sin_addr), htons(ServerAddr.sin_port),buf);
if (!strcmp(buf, "Success"))
{
printf("客户端已就绪...\n");
}
closesocket(msgsock);
}
closesocket(sock);
WSACleanup();
return 0;
} 客户端代码(Client) #include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#define IP "127.0.0.1"
#define PORT 9999 //#ifdef _MSC_VER
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
//#endif int main()
{
while (1)
{
WSADATA WSAData;
SOCKET sock;
struct sockaddr_in ClientAddr; if (WSAStartup(MAKEWORD(2, 0), &WSAData) != SOCKET_ERROR)
{
ClientAddr.sin_family = AF_INET; //指Internet域
ClientAddr.sin_port = htons(PORT); //指定服务端所预留的端口
ClientAddr.sin_addr.s_addr = inet_addr(IP); //指定服务端所绑定的IP地址 sock = socket(AF_INET, SOCK_STREAM, 0);
int Ret = connect(sock, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr));
if (Ret == 0)
{
char Status[] = "Success";
int ServerRet = send(sock, Status, sizeof(Status), 0);
if (ServerRet != 0)
{
printf("发送给服务器Success状态成功..\n");
}
}
}
closesocket(sock);
WSACleanup();
Sleep(5000);
}
return 0;
} 实现Socket单工通信案例 服务端代码(Server) #include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib") //把ws2_32.lib加到Link页的连接库
#define PORT 15001 //通信的端口(指服务器端)
#define ERROR 0
#define BUFFER_SIZE 1024 //注意:此Server端数据接收缓冲区 >= Client端数据发送缓冲区 ,否则造成缓冲区溢出
/*
服务端原理:
1、服务器进程创建套接字
2、将本地地址绑定到所创建的套接字上,以三元组{<通信协议>,<IP地址>,<端口号>}在网络上标识该套接字
3、将套接字置入监听模式,并准备接受连接请求
*/
int main()
{
WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR) //启动winsock ,WSAStartup()函数对Winsock DLL进行初始化
{
printf("Socket initialize fail!\n");
exit(1);
}
SOCKET sock; //服务进程创建套接字句柄(用于监听)
if((sock=socket(AF_INET,SOCK_STREAM,0))==ERROR) //调用socket()函数创建一个流套接字,参数(网络地址类型,套接字类型,网络协议)
{
printf("Socket create!\n");
WSACleanup();
exit(1);
}
struct sockaddr_in ServerAddr; //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构
ServerAddr.sin_family=AF_INET; //sin_family字段必须设为AF_INET,表示该Socket处于Internet域
ServerAddr.sin_port=htons(PORT); //sin_port字段用于指定服务端口,注意避免冲突
ServerAddr.sin_addr.s_addr=INADDR_ANY; //sin_addr字段用于把一个IP地址保存为一个4字节的数,无符号长整型,根据不同用法还可表示本地或远程IP地址
if(bind(sock,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR) //调用bind()函数将本地地址绑定到所创建的套接字上,以在网络上标识该套接字
{
printf("Bind fail!\n");
closesocket(sock);
WSACleanup();
exit(1);
}
printf("Server Socket Port:%d\n",ntohs(ServerAddr.sin_port));
if(listen(sock,10)==SOCKET_ERROR) //调用listen()函数将套接字置入监听模式并准备接受连接请求,参数(已捆绑未连接的套接字描述字,正在等待连接的最大队列长度)
{
printf("Listen fail!\n");
closesocket(sock);
WSACleanup();
exit(1);
} SOCKET msgsock; //创建一个新的套接字(用于接收accept函数的返回值,即表示已经接受的那个客户端的连接,进而接收Client发来的数据)
char buf[BUFFER_SIZE]; //数据接收缓冲区
while(1)
{
if((msgsock=accept(sock,(LPSOCKADDR)0,(int *)0))==INVALID_SOCKET) //进入监听状态后,调用accept()函数接收客户端的连接请求,并把连接传给msgsock套接字,原sock套接字继续监听其他客户机连接请求
{
printf("Accept fail!\n");
continue;
}
memset(buf,0,sizeof(buf)); //初始化数据接收缓冲区
recv(msgsock,buf,BUFFER_SIZE,0); //接收客户端发送过来的数据
if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t') //"exit"命令,退出程序
{
printf("The End.\n");
break;
}
printf("C:\\Socket\\Server>%s",buf);
closesocket(msgsock);
} closesocket(sock); //关闭套接字
WSACleanup(); //终止对Winsock DLL的使用,并释放资源
return 0;
} 客户端代码(Client) #include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib") //把ws2_32.lib加到Link页的连接库
//#define IP "172.18.68.243" //在两台计算机上测试,IP为Server端的IP地址
#define IP "127.0.0.1" //在一台计算机上测试,IP为本地回送地址
#define PORT 15001 //注意:客户端设置通信的端口 = 服务端的端口
#define BUFFER_SIZE 1024 //数据发送缓冲区大小 int main()
{
char buf[BUFFER_SIZE]; //buf数组存放客户端发送的消息
int inputLen; //用于输入字符自增变量
while(1)
{
printf("C:\\Socket\\Client>");
inputLen=0;
memset(buf,0,sizeof(buf));
while((buf[inputLen++]=getchar())!='\n') //输入以回车键为结束标识
{
;
}
if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t')
{
printf("The End.\n");
break;
} WSADATA WSAData;
if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR) //WSAStartup()函数对Winsock DLL进行初始化
{
printf("Socket initialize fail!\n");
continue;
}
SOCKET sock; //客户端进程创建套接字
if((sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR) //创建流套接字(与服务端保持一致)
{
printf("Socket create fail!\n");
WSACleanup();
continue;
} struct sockaddr_in ClientAddr; //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构
ClientAddr.sin_family=AF_INET; //指Internet域
ClientAddr.sin_port=htons(PORT); //指定服务端所预留的端口
ClientAddr.sin_addr.s_addr=inet_addr(IP); //指定服务端所绑定的IP地址
if(connect(sock,(LPSOCKADDR)&ClientAddr,sizeof(ClientAddr))==SOCKET_ERROR) //调用connect()函数,向服务器进程发出连接请求
{
printf("Connect fail!\n");
closesocket(sock);
WSACleanup();
continue;
}
send(sock,buf,BUFFER_SIZE,0); //向服务器发送数据
closesocket(sock); //关闭套接字
WSACleanup(); //终止对Winsock DLL的使用,并释放资源,以备下一次使用
}
return 0;
} 实现Socket双工通信案例 服务端代码(Server) #include <stdio.h>
#include <Winsock2.h> //Socket的函数调用 
#include <windows.h> #define BUF_SIZE 6400 // 缓冲区大小 #pragma comment (lib, "ws2_32") // 使用WINSOCK2.H时,则需要库文件WS2_32.LIB DWORD WINAPI Rcv(LPVOID lpParam)
{
SOCKET sClient = *(SOCKET*)lpParam;
int retVal;
char bufRecv[BUF_SIZE];
memset(bufRecv, 0, sizeof(bufRecv));
while (1)
{
retVal = recv(sClient, bufRecv, BUF_SIZE, 0);
if (retVal == SOCKET_ERROR) {
printf("recive faild!\n");
break;
}
else {
printf("收到客户端消息:%s\n", bufRecv);
}
}
return 0;
} DWORD WINAPI Snd(LPVOID lpParam)
{
SOCKET sClient = *(SOCKET*)lpParam;
int retVal;
char bufSend[BUF_SIZE];
memset(bufSend, 0, sizeof(bufSend));
while (1)
{
gets(bufSend);
retVal = send(sClient, bufSend, strlen(bufSend) + sizeof(char), 0);
if (retVal == SOCKET_ERROR) {
printf("send faild!\n");
break;
}
}
return 0;
} int main(int argc, char* argv[])
{
// 初始化套接字动态库
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("winsock load faild!\n");
return 1;
} // 创建服务段套接字
SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sServer == INVALID_SOCKET) {
printf("socket faild!\n");
WSACleanup();
return -1;
} // 服务端地址
sockaddr_in addrServ; addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(9999);
addrServ.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定套接字
if (bind(sServer, (const struct sockaddr*)&addrServ, sizeof(addrServ)) == SOCKET_ERROR) {
printf("bind faild!\n");
closesocket(sServer);
WSACleanup();
return -1;
} printf("Server is On IP:[%s],port:[%d]\n", inet_ntoa(addrServ.sin_addr), ntohs(addrServ.sin_port)); // 监听套接字 数字表示最多能监听客户个数
if (listen(sServer, 5) == SOCKET_ERROR) {
printf("listen faild!\n");
closesocket(sServer);
WSACleanup();
return -1;
} SOCKET sClient; // 客户端套接字 sockaddr_in addrClient;
int addrClientLen = sizeof(addrClient); sClient = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientLen);
if (sClient == INVALID_SOCKET) {
printf("accept faild!\n");
closesocket(sServer);
WSACleanup();
return -1;
}
printf("accepted client IP:[%s],port:[%d]\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port)); HANDLE hThread1, hThread2;
DWORD dwThreadId1, dwThreadId2; hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID*)&sClient, 0, &dwThreadId1);
hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID*)&sClient, 0, &dwThreadId2); ::WaitForSingleObject(hThread1, INFINITE);
::WaitForSingleObject(hThread2, INFINITE);
::CloseHandle(hThread1);
::CloseHandle(hThread2); closesocket(sClient);
WSACleanup(); // 资源释放 return 0;
} 客户端代码(Client) #include <stdio.h>
#include <Winsock2.h> //Socket的函数调用 
#include <windows.h> #define BUF_SIZE 6400 #pragma comment (lib, "ws2_32") // 使用WINSOCK2.H时,则需要库文件WS2_32.LIB DWORD WINAPI Rcv(LPVOID lpParam)
{
SOCKET sHost = *(SOCKET*)lpParam;
int retVal;
char bufRecv[BUF_SIZE];
memset(bufRecv, 0, sizeof(bufRecv));
while (1)
{
retVal = recv(sHost, bufRecv, BUF_SIZE, 0);
if (retVal == SOCKET_ERROR) {
printf("recive faild!\n");
break;
}
else {
printf("收到服务器消息:%s\n", bufRecv);
}
}
return 0;
} DWORD WINAPI Snd(LPVOID lpParam)
{
SOCKET sHost = *(SOCKET*)lpParam;
int retVal;
char bufSend[BUF_SIZE];
memset(bufSend, 0, sizeof(bufSend));
while (1)
{
gets(bufSend);
retVal = send(sHost, bufSend, strlen(bufSend) + sizeof(char), 0);
if (retVal == SOCKET_ERROR) {
printf("send faild!\n");
break;
}
}
return 0;
} int main(int argc, char* argv[])
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("Winsock load faild!\n");
return 1;
} // 服务器套接字
SOCKET sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sHost == INVALID_SOCKET) {
printf("socket faild!\n");
WSACleanup();
return -1;
} SOCKADDR_IN servAddr;
servAddr.sin_family = AF_INET;
// 注意 当把客户端程序发到别人的电脑时 此处IP需改为服务器所在电脑的IP
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons(9999); // 连接服务器
if (connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
printf("connect faild!\n");
closesocket(sHost);
WSACleanup();
return -1;
}
printf("连接到服务器 IP:[%s],port:[%d]\n", inet_ntoa(servAddr.sin_addr), ntohs(servAddr.sin_port)); HANDLE hThread1, hThread2;
DWORD dwThreadId1, dwThreadId2; hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID)&sHost, 0, &dwThreadId1);
hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID)&sHost, 0, &dwThreadId2); ::WaitForSingleObject(hThread1, INFINITE);
::WaitForSingleObject(hThread2, INFINITE);
::CloseHandle(hThread1);
::CloseHandle(hThread2); closesocket(sHost);
WSACleanup();
return 0;
} 实现文件传输 服务端 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h> #define PORT 8087
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
#pragma comment(lib, "WS2_32") int main()
{
// 声明并初始化一个服务端(本地)的地址结构
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT); // 初始化socket dll
WSADATA wsaData;
WORD socketVersion = MAKEWORD(2, 0);
if (WSAStartup(socketVersion, &wsaData) != 0)
{
printf("Init socket dll error!");
exit(1);
} // 创建socket
SOCKET m_Socket = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET_ERROR == m_Socket)
{
printf("Create Socket Error!");
exit(1);
} //绑定socket和服务端(本地)地址
if (SOCKET_ERROR == bind(m_Socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)))
{
printf("Server Bind Failed: %d", WSAGetLastError());
exit(1);
} //监听
if (SOCKET_ERROR == listen(m_Socket, 10))
{
printf("Server Listen Failed: %d", WSAGetLastError());
exit(1);
} while (1)
{
printf("Listening To Client...\n"); sockaddr_in client_addr;
int client_addr_len = sizeof(client_addr); SOCKET m_New_Socket = accept(m_Socket, (sockaddr *)&client_addr, &client_addr_len);
if (SOCKET_ERROR == m_New_Socket)
{
printf("Server Accept Failed: %d", WSAGetLastError());
break;
} char buffer[BUFFER_SIZE];
memset(buffer, 0, BUFFER_SIZE);
if (recv(m_New_Socket, buffer, BUFFER_SIZE, 0) < 0)
{
printf("Server Receive Data Failed!");
break;
} char file_name[FILE_NAME_MAX_SIZE + 1];
memset(file_name, 0, FILE_NAME_MAX_SIZE + 1);
strncpy(file_name, buffer, strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(buffer));
printf("%s\n", file_name); FILE * fp = fopen(file_name, "rb"); //windows下是"rb",表示打开一个只读的二进制文件
if (NULL == fp)
{
printf("File: %s Not Found\n", file_name);
}
else
{
memset(buffer, 0, BUFFER_SIZE);
int length = 0; while ((length = fread(buffer, sizeof(char), BUFFER_SIZE, fp)) > 0)
{
if (send(m_New_Socket, buffer, length, 0) < 0)
{
printf("Send File: %s Failed\n", file_name);
break;
}
memset(buffer, 0, BUFFER_SIZE);
} fclose(fp);
printf("File: %s Transfer Successful!\n", file_name);
}
closesocket(m_New_Socket);
} closesocket(m_Socket);
//释放winsock库
WSACleanup();
return 0;
} 客户端代码 #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <WinSock2.h> #define PORT 8087
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512
#pragma comment(lib, "WS2_32") int main()
{
// 初始化socket dll
WSADATA wsaData;
WORD socketVersion = MAKEWORD(2, 0);
if (WSAStartup(socketVersion, &wsaData) != 0)
{
printf("Init socket dll error!");
exit(1);
} //创建socket
SOCKET c_Socket = socket(AF_INET, SOCK_STREAM, 0);
if (SOCKET_ERROR == c_Socket)
{
printf("Create Socket Error!");
system("pause");
exit(1);
} //指定服务端的地址
sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
server_addr.sin_port = htons(PORT); if (SOCKET_ERROR == connect(c_Socket, (LPSOCKADDR)&server_addr, sizeof(server_addr)))
{
printf("Can Not Connect To Server IP!\n");
system("pause");
exit(1);
} //输入文件名
char file_name[FILE_NAME_MAX_SIZE + 1];
memset(file_name, 0, FILE_NAME_MAX_SIZE + 1);
printf("Please Input File Name On Server: ");
scanf("%s", &file_name); char buffer[BUFFER_SIZE];
memset(buffer, 0, BUFFER_SIZE);
strncpy(buffer, file_name, strlen(file_name)>BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name)); //向服务器发送文件名
if (send(c_Socket, buffer, BUFFER_SIZE, 0) < 0)
{
printf("Send File Name Failed\n");
system("pause");
exit(1);
} //打开文件,准备写入
FILE * fp = fopen(file_name, "wb"); //windows下是"wb",表示打开一个只写的二进制文件
if (NULL == fp)
{
printf("File: %s Can Not Open To Write\n", file_name);
system("pause");
exit(1);
}
else
{
memset(buffer, 0, BUFFER_SIZE);
int length = 0;
while ((length = recv(c_Socket, buffer, BUFFER_SIZE, 0)) > 0)
{
if (fwrite(buffer, sizeof(char), length, fp) < length)
{
printf("File: %s Write Failed\n", file_name);
break;
}
memset(buffer, 0, BUFFER_SIZE);
} printf("Receive File: %s From Server Successful!\n", file_name);
} fclose(fp);
closesocket(c_Socket); //释放winsock库
WSACleanup(); system("pause");
return 0;
} 使用select 服务端 #include<stdlib.h>
#include<WINSOCK2.H>
#include <windows.h>
#include <process.h> #include<iostream>
#include<string>
using namespace std; #define BUF_SIZE 64
#pragma comment(lib,"WS2_32.lib") void recv(PVOID pt)
{
SOCKET sHost = *((SOCKET *)pt); while (true)
{
char buf[BUF_SIZE];//清空接收数据的缓冲区
memset(buf, 0, BUF_SIZE);
int retVal = recv(sHost, buf, sizeof(buf), 0);
if (SOCKET_ERROR == retVal)
{
int err = WSAGetLastError();
//无法立即完成非阻塞Socket上的操作
if (err == WSAEWOULDBLOCK)
{
Sleep(1000);
printf("\nwaiting reply!");
continue;
}
else if (err == WSAETIMEDOUT || err == WSAENETDOWN || err == WSAECONNRESET)//已建立连接
{
printf("\nrecv failed!");
closesocket(sHost);
WSACleanup();
return;
} } Sleep(100); printf("\n%s", buf);
//break;
}
} int main()
{
WSADATA wsd;
SOCKET sHost;
SOCKADDR_IN servAddr;//服务器地址
int retVal;//调用Socket函数的返回值
char buf[BUF_SIZE];
//初始化Socket环境
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
printf("WSAStartup failed!\n");
return -1;
}
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//设置服务器Socket地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
//在实际应用中,建议将服务器的IP地址和端口号保存在配置文件中
servAddr.sin_port = htons(6000);
//计算地址的长度
int sServerAddlen = sizeof(servAddr); //调用ioctlsocket()将其设置为非阻塞模式
int iMode = 1;
retVal = ioctlsocket(sHost, FIONBIO, (u_long FAR*)&iMode); if (retVal == SOCKET_ERROR)
{
printf("ioctlsocket failed!");
WSACleanup();
return -1;
} //循环等待
while (true)
{
//连接到服务器
retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
if (SOCKET_ERROR == retVal)
{
int err = WSAGetLastError();
//无法立即完成非阻塞Socket上的操作
if (err == WSAEWOULDBLOCK || err == WSAEINVAL)
{
Sleep(1);
printf("check connect!\n");
continue;
}
else if (err == WSAEISCONN)//已建立连接
{
break;
}
else
{
printf("connection failed!\n");
closesocket(sHost);
WSACleanup();
return -1;
}
}
} unsigned long threadId = _beginthread(recv, 0, &sHost);//启动一个线程接收数据的线程 while (true)
{
//向服务器发送字符串,并显示反馈信息
printf("input a string to send:\n");
std::string str;
//接收输入的数据
std::cin >> str;
//将用户输入的数据复制到buf中
ZeroMemory(buf, BUF_SIZE);
strcpy(buf, str.c_str());
if (strcmp(buf, "quit") == 0)
{
printf("quit!\n");
break;
} while (true)
{
retVal = send(sHost, buf, strlen(buf), 0);
if (SOCKET_ERROR == retVal)
{
int err = WSAGetLastError();
if (err == WSAEWOULDBLOCK)
{
//无法立即完成非阻塞Socket上的操作
Sleep(5);
continue;
} else
{
printf("send failed!\n");
closesocket(sHost);
WSACleanup();
return -1;
}
}
break;
} } return 0;
} 客户端 #include <WinSock2.h>
#include <Windows.h>
#include <MSWSock.h>
#include <stdio.h>
#include <map>
using namespace std; #pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib,"Mswsock.lib") int main()
{
WSAData wsaData;
if (0 != WSAStartup(MAKEWORD(2, 2), &wsaData))
{
printf("初始化失败!%d\n", WSAGetLastError());
Sleep(5000);
return -1;
} USHORT nport = 6000;
SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); u_long ul = 1;
ioctlsocket(sListen, FIONBIO, &ul); sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nport);
sin.sin_addr.S_un.S_addr = ADDR_ANY; if (SOCKET_ERROR == bind(sListen, (sockaddr*)&sin, sizeof(sin)))
{
printf("bind failed!%d\n", WSAGetLastError());
Sleep(5000);
return -1;
} listen(sListen, 5); //1)初始化一个套接字集合fdSocket,并将监听套接字放入
fd_set socketSet;
FD_ZERO(&socketSet);
FD_SET(sListen, &socketSet); TIMEVAL time = { 1, 0 };
char buf[4096]; fd_set readSet;
FD_ZERO(&readSet); fd_set writeSet;
FD_ZERO(&readSet); while (true)
{
//2)将fdSocket的一个拷贝fdRead传给select函数
readSet = socketSet;
writeSet = socketSet; //同时检查套接字的可读可写性。
int nRetAll = select(0, &readSet, &writeSet, NULL, NULL/*&time*/);//若不设置超时则select为阻塞
if (nRetAll >0) //-1
{
//是否存在客户端的连接请求。
if (FD_ISSET(sListen, &readSet))//在readset中会返回已经调用过listen的套接字。
{ if (socketSet.fd_count < FD_SETSIZE)
{
sockaddr_in addrRemote;
int nAddrLen = sizeof(addrRemote);
SOCKET sClient = accept(sListen, (sockaddr*)&addrRemote, &nAddrLen);
if (sClient != INVALID_SOCKET)
{
FD_SET(sClient, &socketSet);
printf("\n接收到连接:(%s)", inet_ntoa(addrRemote.sin_addr));
}
}
else
{
printf("连接数量已达上限!\n");
continue;
}
} for (int i = 0; i<socketSet.fd_count; i++)
{
if (FD_ISSET(socketSet.fd_array[i], &readSet))
{
//调用recv,接收数据。
int nRecv = recv(socketSet.fd_array[i], buf, 4096, 0);
if (nRecv > 0)
{
buf[nRecv] = 0;
printf("\nrecv %d : %s", socketSet.fd_array[i], buf);
}
} if (FD_ISSET(socketSet.fd_array[i], &writeSet))
{ //调用send,发送数据。
char buf[] = "hello!";
int nRet = send(socketSet.fd_array[i], buf, strlen(buf) + 1, 0);
if (nRet <= 0)
{
if (GetLastError() == WSAEWOULDBLOCK)
{
//do nothing
}
else
{
closesocket(socketSet.fd_array[i]);
FD_CLR(socketSet.fd_array[i], &socketSet);
}
}
else
{
printf("\nsend hello!");
}
}
} }
else if (nRetAll == 0)
{
printf("time out!\n");
}
else
{
printf("select error!%d\n", WSAGetLastError());
Sleep(5000);
break;
} Sleep(1000); }
closesocket(sListen);
WSACleanup();
}

C/C++ 创建Socket实现双工通信的更多相关文章

  1. C# Socket系列二 简单的创建 socket 通信

    看了系列一 我们开启了对socket tcp的监听状态,那么这一章我们来讲解怎么创建socket的通信代码 我新建一个类 TSocketBase public abstract class TSock ...

  2. 如何使用HTML5的WebSocket实现网页与服务器的双工通信(二)

    本系列服务端双工通信包括两种实现方式:一.使用Socket构建:二.使用WCF构建.本文为使用WCF构建服务端的双工通信,客户端同样使用Html5的WebSocket技术进行调用. 一.创建WCF服务 ...

  3. 如何使用HTML5的WebSocket实现网页与服务器的双工通信(一)

    本系列服务端双工通信包括两种实现方式:一.使用Socket构建:二.使用WCF构建.本文为使用Socket构建服务端的双工通信,客户端同样使用Html5的WebSocket技术进行调用. 一.网页客户 ...

  4. Wcf 双工通信的应用

    概述 双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工ME ...

  5. 使用TCP/IP的套接字(Socket)进行通信

    http://www.cnblogs.com/mengdd/archive/2013/03/10/2952616.html 使用TCP/IP的套接字(Socket)进行通信 套接字Socket的引入 ...

  6. [转载]WCF实现双工通信

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  7. 我的WCF之旅(3):在WCF中实现双工通信

    双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向对方发送消息.基于双工MEP消息交换可以看成是多个基本模式下(比如请求-回复模式和单项模式)消息交换的组合.双工MEP又具 ...

  8. PHP创建socket服务

    PHP可以创建socket服务. 先熟悉几个php网络方面的函数,操作手册地址  http://php.net/manual/zh/ref.sockets.php 简单介绍下socket,它表示套接字 ...

  9. linux c使用socket进行http 通信,并接收任意大小的http响应(四)

    终于说到SOCKET 这里了.SOCKET进行http通信的实际就是利用socket将http请求信息发送给http服务器,然后再利用socket接收http响应. 由于本文与之通信的服务器是ip已知 ...

  10. linux c使用socket进行http 通信,并接收任意大小的http响应(三)

    使用socket进行http通信的时候,浏览器返回的响应经常不是固定长度的,有时候很大,有些时候又非常小,十分讨厌.如果仅仅只是为了接收一小段信息,设置一个十分大的缓存,这样又会十分浪费.而且经常更改 ...

随机推荐

  1. 【前端】2024年 前端Base64编码的中文处理问题

    window.btoa() 遇到中文要出问题 localStorage.setItem("token",window.btoa(unescape(encodeURIComponen ...

  2. Write failed: Broken pipe > Couldn‘t read packet: Connection reset by peer SFTP服务器连接出现的问题

    如果你链接服务器的时候出现下面的提示: Write failed: Broken pipeCouldn't read packet: Connection reset by peer这个问题的原因是C ...

  3. OpenLens 6.3.0 无法查案日志和进入 Pod Shell 解决方法

    原因 OpenLens 6.3.0开始移除了Pod的查看日志和进入Pod Shell按钮,无法查看日志和进入Pod操作. 解决办法 OpenLens 6.3.0开始这两个功能以插件形式提供,需下载op ...

  4. Docker OCI runtime exec failed: exec failed: container_linux.go:344: starting container process caus

    docker执行命令:docker exec -it 1e33b26152e1 /bin/bash 在进入容器报错:OCI runtime exec failed: exec failed: cont ...

  5. 怎么在 Linux 下运行 smart_rtmpd

    怎么在 Linux 下运行 smart_rtmpd 操作系统的准备 我们知道比较流行的 Linux 操作系统基本上分为两类,一类是以 Redhat 为基线的 Redhat, CentOS:另一类是 D ...

  6. 敏捷开发:如何高效开每日站会(Daily Stand-up Meeting)

    介绍 在敏捷开发框架 Scrum 中,每日站会(Daily Stand-up Meeting,又叫 Daily Scrum)是 Sprint 迭代开发中,一个很重要的流程,一个重要的例会.在有限的时间 ...

  7. WPF刮刮乐

    WPF刮刮乐 <Window x:Class="WpfApp2.MainWindow" xmlns="http://schemas.microsoft.com/wi ...

  8. yolov5输出解码实现

    yolov5输出解释--以yolov5s.pt为例 写在前面.这几天在用Tensort部署一个工训赛检测圆环的模型,发现输出怎么都对不上,通过查阅各方资料,便有了这篇文章,希望能帮助到大家 输出维度 ...

  9. manim边做边学--淡入淡出变换

    今天介绍Manim中用于淡入淡出变换的3个动画类: FadeToColor:聚焦于对象颜色的平滑转换,通过渐变增强视觉效果 FadeTransform:实现不同对象之间的渐变替换,让元素转换更加连贯 ...

  10. uniapp横向滚动

    scroll-x="true" 出现横向滚动 scroll-with-animation="true" 横向滚动有动画 <scroll-view clas ...