Windows 篇
#pragma comment(lib,"ws2_32.lib")
#include <WinSock2.h>
#include <Windows.h>
//初始化WSA
WSAData wsaData;
WSAStartup(WINSOCK_VERSION, &wsaData);
//创建套接字
SOCKET clientSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (clientSock == INVALID_SOCKET){
WSACleanup();
return -1;
}
//设置服务端重新bind
bool bReuseAddr = true;
iRet = setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&bReuseAddr, sizeof(bReuseAddr));
if (SOCKET_ERROR == iRet){
WSACleanup();
return -1;
}
//绑定IP和端口
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(8888);
serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
if (bind(listen_sock, (LPSOCKADDR)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR){
WSACleanup();
return -1;
}
//开始监听
if (listen(listen_sock, 1024) == SOCKET_ERROR){
WSACleanup();
Log_Info("listen error !");
return -1;
}
//阻塞接收客户端请求...
accept(g_listen_sock, (SOCKADDR*)&remoteAddr, &iAddrlen);
sockaddr_in clientAddr;
memset(&clientAddr, 0x00, sizeof(clientAddr));
clientAddr.sin_family = AF_INET;
clientAddr.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
clientAddr.sin_port = htons(SERVER_PORT);
int iRet = connect(clientSock, (sockaddr*)&clientAddr, sizeof(clientAddr));
if (0 != iRet){
WSACleanup();
return -1;
}
int recv(SOCKET sockfd, char* recvBuf, int data_len, 0);
int send(SOCKET sock, char* sendBuf, int iSendLen, 0);
Linux篇
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
int sockfd;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0){
close(sockfd);
return -1;
}
//允许服务端重新bind 服务器IP:Port
int reuse_addr_flag = 1;
iRet = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr_flag, sizeof(reuse_addr_flag));
if (-1 == iRet){
close_connect(sock);
return -1;
}
memset(&listen_addr, 0, sizeof(listen_addr));
listen_addr.sin_family = AF_INET;
listen_addr.sin_port = htons(server_port);
listen_addr.sin_addr.s_addr = htonl(0);
iRet = bind(sock, (struct sockaddr*)&listen_addr, sizeof(listen_addr));
if (-1 == iRet){
close_connect(sock);
return -1;
}
iRet = listen(sock, /*SOMAXCONN*/1024);
if (-1 == iRet){
close_connect(sock);
return -1;
}
struct sockaddr_in server_addr;
memset(&server_addr, 0x00, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
close(sockfd);
return -1;
}
int recv(SOCKET sockfd, char* recvBuf, int data_len, 0);
int send(SOCKET sock, char* sendBuf, int iSendLen, 0);
win & Linux平台 socket通用接口 (部分)##
1.accept(g_listen_sock, (SOCKADDR*)&remoteAddr, &iAddrlen);
2.send(sock, pBuf, iSendLen, 0);
3.recv(sockfd, recvBuf, data_len, 0);
4.select非阻塞监听文件描述符是否可读:
struct timeval tm_out;
fd_set read_fds;
FD_ZERO(&read_fds);
FD_SET(sock, &read_fds);
tm_out.tv_sec = 5;
tm_out.tv_usec = 0;
int iRet = select(sock + 1, //监视最大描述符
&read_fds, //监视sock是否可读, 结果集
NULL, //是否可写
NULL, //错误描述符
&tm_out);//超时时间
switch (iRet)
{
case -1: //出错返回-1
return -1;
case 0: //超时返回0
return 0;
default: //大于0表示当前sock可读或可写
break;
}