張會勇老師《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是非面向連線的,沒有乙個客戶端可以老是佔住服務端.只要處理過程不是死迴圈,伺服器對於...