基於
winsocket
的單執行緒
server
的實現
功能描述:
程式實現乙個server監聽埠的功能,執行後,其處於監聽狀態。當有client連線到此server,它停止監聽,接收到自此client的資料,並將從client收到資料反射給client。
呼叫順序:
1. wsastartup:開始對ws2_32.dll的使用。
2. socket:建立乙個socket。
3. bind:繫結ip與port。
4. listen:監聽乙個socket。
5. accept:接受client的連線。
6. send:向指定socket傳送資料。
7. recv:從指定的socket接收資料。
8. wsacleanup:關閉對ws2_32.dll的使用。
函式說明;
intwsastartup(
word
wversionrequested
,lpwsadata
wversionrequested
,lpwsadata
lpwsadata );
//initialize a wsadata object
wsadata wsadata;
int nresult = wsastartup(makeword(2,2),&wsadata);
socket
socket(
intaf
,intaf,
inttype
,int
protocol );
功能:建立乙個繫結到指定service provider上的socket。
//create a socket
socket m_socket;
m_socket = socket(af_inet,sock_stream,ipproto_tcp);
intbind(
sockets,
const struct sockaddr*s,
const struct sockaddr*
name
,int
namelen );
//bind a socket
sockaddr_in service;
service.sin_family = af_inet;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(27002);
if(bind(m_socket,(sockaddr*)&service,sizeof(service)) == socket_error)
intlisten(
sockets,
ints
,int
backlog );
功能:將乙個socket置於監聽狀態。
//listen on a socket
if(listen(m_socket,20) == socket_error)
socket
accept(
sockets,
struct sockaddr*s,
struct sockaddr*
addr
,int*
addrlen );
功能:接受來自外部的client連線,返回乙個新的socket。
acceptsocket = socket_error;
while (acceptsocket == socket_error)
intrecv(
sockets,
char*s,
char*
buf,
intlen
,int
len,
intflags );
功能:從指定的socket中接收資料。
int nsendbytes = 0;
int nrecvbytes = 0;
char precvbytes[32] = "";
nrecvbytes = recv(m_socket,precvbytes,32,0);
cout << "num of receive :" << nrecvbytes << endl;
cout << precvbytes << endl;
intsend(
sockets,
const char*s,
const char*
buf,
intlen
,int
len,
intflags );
功能:向已連線的socket傳送資料。
char psendbytes[32] = "server:send data";
nsendbytes = send(m_socket,psendbytes,32,0);
intwsacleanup(void);
功能:關閉能ws2_32.dll的使用,呼叫次數應該與wsastartup相同。
wsacleanup();
完整**
#include
#include
"winsock2.h"
#include
using
namespace std;
intmain()
//建立乙個socket
socket m_socket;
m_socket = socket(af_inet, //協議族
sock_stream, //socket型別
ipproto_tcp); //此socket使用的協議
if(m_socket == invalid_socket)
//bind a socket
sockaddr_in service;
service.sin_family = af_inet;//協議族
service.sin_addr.s_addr = inet_addr("127.0.0.1");//ip位址
service.sin_port = htons(27002); //埠號
//將socket與指定的位址繫結
if(bind(m_socket,(sockaddr*)&service,sizeof(service)) == socket_error)
//監聽socket
if(listen(m_socket,20) == socket_error)
//接受乙個socket連線
socket acceptsocket;
cout << "waiting for client to connect" << endl;
while (1)
cout << "client connected!" << endl;
m_socket = acceptsocket;
break;
}
int nsendbytes = 0;
int nrecvbytes = 0;
char psendbytes[32] = "server:send data";
char precvbytes[32] = "";
//從socket接收資料.
nrecvbytes = recv(m_socket,precvbytes,32,0);
cout << "num of receive :" << nrecvbytes << endl;
cout << precvbytes << endl;
//向socket傳送資料。
nsendbytes = send(m_socket,psendbytes,32,0);
if (nsendbytes == socket_error) else
cout <<"num of send : " << nsendbytes << endl;
//清除ws2_32.dll
sleep(5000);
wsacleanup();
return 0;
}
php 單執行緒
php 從設計之初到流行起來都沒有出現明顯需要用多執行緒才能解決的需求。某些需要用到多執行緒的地方也有相應的解決方案和替代方案。多執行緒並不總是比單執行緒優,多執行緒可能會引入其他問題 例如 兩個執行緒同時呼叫乙個類裡的同乙個方法時,可能出現死鎖的情況 每個 php 檔案的執行是單執行緒的,但是,伺...
Redis單執行緒
redis 的單執行緒主要是指 redis 的網路 io 和鍵值對讀寫是由乙個執行緒來完成的,這也是 redis 對外提供鍵值儲存服務的主要流程。當多個客戶端發起命令,這些命令併發執行時,在redis內部,會排隊逐個執行,也就是執行命令的那個操作是由乙個執行緒執行的。但 redis 的其他功能,比如...
單執行緒時代
了解了 reactor 模式後,你可能會有乙個疑問,這個和我們今天的主題有什麼關係呢。可能你不知道的是,redis 是基於 reactor 單執行緒模式來實現的。io多路復用程式接收到使用者的請求後,全部推送到乙個佇列裡,交給檔案分派器。對於後續的操作,和在 reactor 單執行緒實現方案裡看到的...