C語言 Socket基礎接口(Windows & Linux)

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;
	}
  • server端
//設置服務端重新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);
  • client:
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篇

  • server & client 頭部
#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;
	}
  • server:
//允許服務端重新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;
	}
  • client:
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;
	}
	
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章