基於TCP的Socket通訊 多執行緒

2021-09-25 15:02:28 字數 3535 閱讀 5354

**中引用的頭函式

#include #include #include #pragma comment(lib,"ws2_32.lib")
伺服器端:

1.初始化socket環境,建立套接字

wsadata wsadata;

word wversionrequested = makeword(2, 2); //將兩個byte型合成乙個word型

if (wsastartup(wversionrequested, &wsadata) != 0)

socket tcpsocket, s_accept; //建立伺服器端的套接字tcpsocket,對端套接字s_accept(會由accept()函式返回)

int len1; //定義對端位址長度引數

tcpsocket = socket(af_inet, sock_stream, 0); //定義套接字,第乙個引數表示使用ipv4,第二個引數表示流式套接字用於tcp,第三個引數代表協議型別,0表示任何

//設定伺服器位址等資訊

localaddr.sin_family = af_inet; //設定伺服器端使用ipv4通訊

localaddr.sin_port = htons(localport); //設定伺服器端的埠號

localaddr.sin_addr.s_addr = inet_addr(localip); //設定伺服器端的ip位址

//伺服器端套接字和位址資訊的繫結

int bind = bind(tcpsocket, (struct sockaddr*)&localaddr, len);//繫結tcpsocket和上面設定的localaddr

if (bind == socket_error)

監聽客戶端是否有連線請求

listen(tcpsocket, somaxconn);						 //監聽伺服器端的套接字,第乙個引數表示要監聽的物件,第二個表示監聽的最大佇列長度

cout << "服務端正在監聽連線,請稍候...." << endl;

接受連線

len1 = sizeof(sockaddr);						    //客戶端的位址長度引數

s_accept = accept(tcpsocket, (sockaddr *)&accept_addr, &len1);//伺服器接受來自客戶機的連線請求,返回客戶機的套接字作為以後的通訊位址

if (s_accept == socket_error)

cout << "連線建立,準備接受資料" << endl;

開啟多執行緒收發

handle hthrdsnd, hthrdrcv;						   //定義傳送執行緒和接收執行緒

dword nthrdsnd, nthrdrcv; //返回的執行緒id號

/*使用creatthread()建立執行緒,

第乙個引數表示核心物件安全屬性;

第二個引數表示執行緒棧空間大小,0表示預設1mb;

第三個引數表示執行緒執行的執行緒函式位址

第四個引數表示傳遞給執行緒函式的引數,本執行緒中傳遞的是對端的套接字

第五個引數表示額外的標誌,用來控制線程的建立,0表示建立完之後執行緒立即執行,creat_suspended表示建立後暫停執行,直到呼叫resumethread()函式

第六個引數表示返回的執行緒號

*/ hthrdsnd = createthread(null, 0, (lpthread_start_routine)sendmessage, (lpvoid)s_accept, 0, &nthrdsnd);

hthrdrcv = createthread(null, 0, (lpthread_start_routine)recvmessage, (lpvoid)s_accept, 0, &nthrdrcv);

/* 希望執行緒完成後才繼續執行主程序,直到bexit事件被啟用(由setevent()觸發事件的函式啟用),

主程序才繼續執行

*/ waitforsingleobject(bexit, infinite);

接收和傳送執行緒函式

//接收執行緒函式

dword winapi recvmessage(lpvoid parsock)

} else

//cout << "recive error" << err << endl;

setevent(bexit); break;

} }closesocket(recvsock); //關閉套接字

wsacleanup();

return 0;

}//傳送資料執行緒函式

dword winapi sendmessage(lpvoid parsock)

} closesocket(sendsock);

wsacleanup();

return 0;

}

客戶端:

定義套接字,初始化環境

//初始化ddl

wsadata wsadata;

word wversionrequested = makeword(2, 2);

if (wsastartup(wversionrequested, &wsadata) != 0)

//設定乙個多執行緒停止事件

bexit = wsacreateevent();

//定義套接字包括伺服器位址和埠號

socket tcpsocket;

string add;

unsigned short port;

getline(cin, add);

const char*s = add.c_str();

//server_addr.sin_family = af_inet;

//server_addr.sin_addr.s_un.s_addr = inet_addr(s);

cout << "輸入埠號:";

cin >> port;

cin.ignore();

//server_addr.sin_port = htons(port);

localaddr.sin_family = af_inet;

localaddr.sin_port = htons(port);

localaddr.sin_addr.s_addr = inet_addr(s);

tcpsocket = socket(af_inet, sock_stream, 0);

連線伺服器

if (connect(tcpsocket, (sockaddr *)&localaddr, sizeof(sockaddr)) == socket_error) 

else

開啟多執行緒收發(同伺服器端)

接收和傳送執行緒函式(同伺服器端)

基於TCP的Socket通訊

在win32平台上的winsock程式設計都要經過下列步驟 定義變數 獲得windock版本 載入winsock庫 初始化 建立套接字 設定套接字選項 關閉套接字 解除安裝winsock庫 釋放資源 1 建立乙個socket,用函式socket int socket int domain,int t...

基於tcp的socket通訊

socekt是應用層與tcp ip協議族通訊的中間軟體抽象層,它是一組介面。在設計模式中,socket其實就是乙個門面模式,它 把複雜的tcp ip協議族隱藏在socket介面後面,對使用者來說,一組簡單的介面就是全部,讓socket去組織資料,以符合指定的協議 socket 基於檔案型別的套接字家...

基於TCP協議的socket通訊

一 伺服器端 1 建立serversocket,即伺服器端的socket,繫結指定的埠,並偵聽此埠 serversocket server new serversocket 8888 2 呼叫accept 方法,開始偵聽,等待客戶端的連線,在未連線成功之前,處於阻塞狀態,返回的socket,用於與客...