socket I O多路復用 select函式

2021-06-22 01:10:25 字數 4693 閱讀 6494

張會勇老師《winsocket網路程式設計經絡》,中外windowssocket的良心之作。

見**吧。

標頭檔案

#pragma once

#define msg_send_version 'b'

#define msg_send_port 18

#define msg_buf_size 512

//函式返回值

#define msg_success 0

#define msg_version_error -1

#define msg_field_error -2

//訊息欄位的列舉值

enum msp_field

;struct field_name

;

實現

#include #include #include "msgserver.h"

#pragma comment(lib,"ws2_32.lib")

//message send protocol欄位原列舉值對應的名字

static struct field_name msp_info[msp_total] = ,

, ,, ,

, , };

static socket msp_client_socket [fd_setsize]; //用來接收客戶端的連線

static unsigned int client_max;

int handle_error(socket s1,socket s2,int exit)

//接收客戶端的連線請求

// listen_socket服務端監聽的socket

//socket_set新接收的socket需要加入此集合

//返回成功返回新接收的client_socket,失敗返回invalid_socket

socket msp_new_client(socket listen_socket, pfd_set socket_set)

printf ("[msp] accept connection: %s\n",inet_ntoa(client_address.sin_addr));

for (unsigned int i = 0; i < fd_setsize; i++) }

closesocket(client_socket); //遍歷fd_setsize,無可用位置,只能關閉client_socket,暫不處理,返回

return invalid_socket;

}//關閉客戶端的套介面描述符,套介面從集合socket_set中移除

//void msp_close_client(int index, fd_set* socket_set)

//將接收的資料填寫到buf中

int msp_recv_data(int i, char* buf, int len, psockaddr_in from)

else

return result;

}int msp_process_request(char* buf, int len)

; int i = msp_recip;

if (msg_send_version != buf[0]) //版本檢查

//解析其它字段

msp_field[msp_recip] = ++buf;

char *sep = (char*)memchr(buf, 0, buf_end - buf);

while (sep && sep < buf_end)

buf = sep + 1;

sep = (char*)memchr(buf, 0, buf_end - buf);

} if (i != msp_signat)

//顯示

printf ("------------------------\n");

for (int i = msp_recip; i < msp_total; i++)

printf ("------------------------\n");

return msg_success;

}int msp_send_reply(int i, int error, psockaddr_in from)

; msg = reply_description[error];

msg_len = strlen(msg);

if (0 == i)

else

return result;

}int main (int __argc, char** __argv)

wsadata wsa;

if (wsastartup(makeword(2,2), &wsa))

socket msp_server_socket_tcp = socket(af_inet, sock_stream, 0);

if (invalid_socket == msp_server_socket_tcp)

sockaddr_in server_address;

server_address.sin_family = af_inet;

server_address.sin_port = htons(msg_send_port);

server_address.sin_addr.s_addr = inaddr_any;

int result = bind(msp_server_socket_tcp, (psockaddr)&server_address, sizeof(sockaddr));

if (socket_error == result)

result = listen(msp_server_socket_tcp,somaxconn);

if (socket_error == result)

socket msp_server_socket_udp = socket(af_inet, sock_dgram, 0);

if (invalid_socket == msp_server_socket_udp)

result = bind(msp_server_socket_udp,(psockaddr)&server_address, sizeof(server_address));

if (socket_error == result)

fd_set read_set, read_all;

fd_zero(&read_all);

fd_set(msp_server_socket_tcp, &read_all);

fd_set(msp_server_socket_udp, &read_all);

msp_client_socket[0] = msp_server_socket_udp; //upd socket 固定在第乙個位置

printf ("[msp] server is running...\n");

int ready_count ;

socket new_socket,client_socket;

sockaddr_in client_address;

char recv_buf[msg_buf_size+1];

while (1)

if (fd_isset(msp_server_socket_tcp,&read_set)) //檢查描述符是否在集合中

}//有客戶端傳送資料,進入下面的for迴圈

for (unsigned int i = 0; i <= client_max && ready_count > 0; i++)

if (!fd_isset(client_socket,&read_set))

result = msp_recv_data(i, recv_buf, msg_buf_size, &client_address);

if (0 == i) //msp_client_socket[0],udp, recvfrom(,,,&client_address,);

if (result <= 0)

result = msp_process_request(recv_buf, result);

result = msp_send_reply(i, result, &client_address);

if (socket_error == result)

--ready_count;

} }for (unsigned int i = 0; i < client_max; i++)

closesocket(msp_server_socket_tcp);

wsacleanup();

return exit_success;

}

執行結果:

>msgserver.exe

[msp] server is running...

[msp] accept connection: 192.168.2.102

------------------------

recipient:zeek

recip-term:console

message:come on

sender:me

sender-term:console

cookie:20140513230733

signature:empty

------------------------

Linux IO多路復用

一.select 函式 include include include int select int n,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout fd clr int fd,fd set set f...

I O多路復用

一 五種i o模型 1 阻塞i o模型 最流行的i o模型是阻塞i o模型,預設情形下,所有套介面都是阻塞的。我們以資料報套介面為例來講解此模型 我們使用udp而不是tcp作為例子的原因在於就udp而言,資料準備好讀取的概念比較簡單 要麼整個資料報已經收到,要麼還沒有。然而對於tcp來說,諸如套介面...

Linux C Socket多路復用

1.迴圈伺服器 udp伺服器 udp迴圈伺服器的實現非常簡單 udp伺服器每次從套接字上讀取乙個客戶端的請求,處理,然後將結果返回給客戶機.可以用下面的演算法來實現.socket bind while 1 因為udp是非面向連線的,沒有乙個客戶端可以老是佔住服務端.只要處理過程不是死迴圈,伺服器對於...