當前位置:編程學習大全網 - 編程語言 - 畢業論文《基於socket 的局域網聊天工具》,要求C++語音編寫,要有程序,能實現,有文檔……

畢業論文《基於socket 的局域網聊天工具》,要求C++語音編寫,要有程序,能實現,有文檔……

“對圖中的那些函數,我這裏稍加解釋壹下。”

int?WSAStartup(WORD?wVersionRequested,?LPWSADATA?lpWSAData);?

功能是初始化Windows?Socket?Dll,在Windows下必須使用它。

參數:

“wVersionRequested”表示版本,可以是1.1、2.2等;

“lpWSAData”指向WSADATA數據結構的指針。

int?socket(int?family,?int?type,?int?protocol);?

功能是建立Socket,返回以後會用到的Socket值。如果錯誤,返回-1。

參數:

“int?family”參數指定所要使用的通信協議,取以下幾個值:AF_UNIX(Unix內部協議)、AF_INET(Internet協議)、AF_NS?Xerox(NS協議)、AF_IMPLINK(IMP連接層),在Windows下只能把“AF”設為“AF_INET”;

“int?type”參數指定套接字的類型,取以下幾個值:SOCK_STREAM(流套接字)、SOCK_DGRAM?(數據報套接字)、SOCK_RAW(未加工套接字)、SOCK_SEQPACKET(順序包套接字);

“int?protocol”參數通常設置為0。

int?bind(int?sockfd,?struct?sockaddr?*my_addr,?int?addrlen);?

功能是把套接字和機器上壹定的端口關聯起來。

參數:

“sockfd”是調用socket()返回的套接字值;

“my_addr”是指向數據結構struct?sockaddr的指針,它保存妳的地址,即端口和IP地址信息;

“addrlen”設置為sizeof(struct?sockaddr)。?

int?listen(int?sockfd,?int?backlog);?

功能是服務端監聽壹個端口,直到accept()。在發生錯誤時返回-1。

參數:

“sockfd”是調用socket()返回的套接字值;

“backlog”是允許的連接數目。大多數系統的允許數目是20,也可以設置為5到10。

int?connect(int?sockfd,?struct?sockaddr?*serv_addr,?int?addrlen);?

功能是客戶端連接服務端監聽的端口。

參數:

“sockfd”是調用socket()返回的套接字值;

“serv_addr”保存著目的地端口和IP?地址的數據結構struct?sockaddr;

“addrlen”設置為sizeof(struct?sockaddr)。?

int?accept(int?sockfd,?void?*addr,?int?*addrlen);?

功能是服務端接受客戶端的連接請求,並返回壹個新的套接字,以後服務端的數據傳輸就使用這個新的套接字。如果有錯誤,返回-1。

參數:

“sockfd”是和listen()中壹樣的套接字值;

“addr”是個指向局部的數據結構sockaddr_in的指針;

“addrlen”設置為sizeof(struct?sockaddr_in)。

int?send(int?sockfd,?const?void?*msg,?int?len,?int?flags);

int?recv(int?sockfd,?void?*buf,?int?len,?unsigned?int?flags);

功能是用於流式套接字或數據報套接字的通訊,我們數據的真正傳輸就由它們完成。

參數:

“sockfd”是發/收數據的套接字值;

“msg”指向妳想發送的數據的指針;

“buf”是指向接收數據存放的地址;

“len”是數據的長度;

“flags”設置為?0。

int?sendto(int?sockfd,?const?void?*msg,?int?len,?unsigned?int?flags,const?struct?sockaddr?*to,?int?tolen);

int?recvfrom(int?sockfd,?void?*buf,?int?len,?unsigned?int?flags,? struct?sockaddr?*from,?int?*fromlen);

功能和send、recv類似,不過是用於無連接數據報套接字的傳輸。

int?closesocket(int?sockfd)?

功能是關閉套接字。

參數“sockfd”為要關閉的套接字值。

程序:

“這裏的目的是讓大家對Socket編程有個整體了解。不用怕,程序我會詳細解釋的,首先是服務端的程序。其流程是:

socket()→bind()→listen→accept()→recv()/send()→closesocket()?

具體代碼如下:”

#include?<stdio.h>

#include?<winsock.h>

#pragma?comment(lib,"Ws2_32")

#define?MYPORT?830?/*定義用戶連接端口*/?

#define?BACKLOG?10?/*多少等待連接控制*/?

int?main()?

{

int?sockfd,?new_fd;?/*定義套接字*/

struct?sockaddr_in?my_addr;?/*本地地址信息?*/?

struct?sockaddr_in?their_addr;/*連接者地址信息*/?

int?sin_size;

WSADATA?ws;

WSAStartup(MAKEWORD(2,2),&ws);//初始化Windows?Socket?Dll

//建立socket

if?((sockfd?=?socket(AF_INET,?SOCK_STREAM,?0))?==?-1)

{?

//如果建立socket失敗,退出程序

printf("socket?error\n");?

exit(1);?

}?

//bind本機的MYPORT端口

my_addr.sin_family?=?AF_INET;?/*?協議類型是INET?*/?

my_addr.sin_port?=?htons(MYPORT);/*?綁定MYPORT端口*/?

my_addr.sin_addr.s_addr?=?INADDR_ANY;/*?本機IP*/?

if?(bind(sockfd,?(struct?sockaddr?*)&my_addr,?sizeof(struct?sockaddr))==?-1)

{?

//bind失敗,退出程序

printf("bind?error\n");?

closesocket(sockfd);

exit(1);?

}

//listen,監聽端口

if?(listen(sockfd,?BACKLOG)?==?-1)

{?

//listen失敗,退出程序

printf("listen?error\n");?

closesocket(sockfd);

exit(1);?

}?

printf("listen...");

//等待客戶端連接

sin_size?=?sizeof(struct?sockaddr_in);?

if?((new_fd?=?accept(sockfd,?(struct?sockaddr?*)&their_addr,?&sin_size))?==?-1)

{?

printf("accept?error\n");?

closesocket(sockfd);

exit(1);

}?

printf("\naccept!\n");

//有連接,發送ww0830字符串過去

if?(send(new_fd,?"ww0830\n",?14,?0)?==?-1)?

{

printf("send?error");

closesocket(sockfd);

closesocket(new_fd);?

exit(1);?

}?

printf("send?ok!\n");

//成功,關閉套接字

closesocket(sockfd);

closesocket(new_fd);

return?0;

}

對服務端程序的流程概括:

先是初始化Windows?Socket?Dll:?WSAStartup(MAKEWORD(2,2),&ws);?

然後建立Socket:?sockfd?=?socket(AF_INET,?SOCK_STREAM,?0)?

再bind本機的MYPORT端口:

my_addr.sin_family?=?AF_INET;?/*?協議類型是INET*/?

my_addr.sin_port?=?htons(MYPORT);/*?綁定MYPORT端口?*/?

my_addr.sin_addr.s_addr?=?INADDR_ANY;/*?本機IP*/?

bind(sockfd,?(struct?sockaddr?*)&my_addr,?sizeof(struct?sockaddr))?

接下來監聽端口:?listen(sockfd,?BACKLOG)?

如果有客戶端的連接請求,接收它:?new_fd?=?accept(sockfd,?(struct?sockaddr?*)&their_addr,?&sin_size)?

最後發送ww0830字符串過去:?send(new_fd,?"ww0830\n",?14,?0)?

收尾工作,關閉socket:?closesocket(sockfd);closesocket(new_fd);?”

編譯、執行,就會壹直監聽830端口

客戶端程序了。其流程是:

socket()→connect()→send()/recv()→closesocket()?

比服務端更簡單吧!其實現代碼如下:”

#include?<stdio.h>

#include?<stdio.h>

#include?<winsock.h>

#pragma?comment(lib,"Ws2_32")

#define?PORT?830/*?客戶機連接遠程主機的端口?*/?

#define?MAXDATASIZE?100?/*?每次可以接收的最大字節?*/?

int?main(int?argc,?char?*argv[])?

{?

int?sockfd,?numbytes;?

char?buf[MAXDATASIZE];?

struct?sockaddr_in?their_addr;/*?對方的地址端口信息?*/?

if?(argc?!=?2)?

{?

//需要有服務端ip參數

fprintf(stderr,"usage:?client?hostname\n");?

exit(1);?

}?

 WSADATA?ws;

WSAStartup(MAKEWORD(2,2),&ws);?//初始化Windows?Socket?Dll

if?((sockfd?=?socket(AF_INET,?SOCK_STREAM,?0))?==?-1)

{?

//如果建立socket失敗,退出程序

printf("socket?error\n");?

exit(1);?

}?

//連接對方

their_addr.sin_family?=?AF_INET;?/*?協議類型是INET?*/?

their_addr.sin_port?=?htons(PORT);/*?連接對方PORT端口?*/?

their_addr.sin_addr.s_addr?=?inet_addr(argv[1]);/*?連接對方的IP?*/?

if?(connect(sockfd,?(struct?sockaddr?*)&their_addr,sizeof(struct?sockaddr))?==?-1)

{?

//如果連接失敗,退出程序

printf("connet?error\n");?

closesocket(sockfd);?

exit(1);?

}?

//接收數據,並打印出來

if?((numbytes=recv(sockfd,?buf,?MAXDATASIZE,?0))?==?-1)?

{?

//接收數據失敗,退出程序

printf("recv?error\n");?

closesocket(sockfd);?

exit(1);?

}?

buf[numbytes]?=?'\0';?

printf("Received:?%s",buf);?

closesocket(sockfd);?

return?0;?

}?

對客戶端程序的流程概括:

首先是初始化Windows?Socket?Dll:?WSAStartup(MAKEWORD(2,2),&ws);?

然後建立Socket:?sockfd?=?socket(AF_INET,?SOCK_STREAM,?0)?

接著連接服務器方:

their_addr.sin_family?=?AF_INET;?/*?協議類型是INET*/?

their_addr.sin_port?=?htons(PORT);/*?連接對方PORT端口?*/?

their_addr.sin_addr.s_addr?=?inet_addr(argv[1]);?/*?連接對方的IP?*/?

connect(sockfd,?(struct?sockaddr?*)&their_addr,sizeof(struct?sockaddr))?

連接成功就接收數據:?recv(sockfd,?buf,?MAXDATASIZE,?0)?

最後把收到的數據打印出來並關閉套接字:

printf("Received:?%s",buf);?closesocket(sockfd);?

編譯結束後,運行服務端,然後。客戶端?服務端IP?回車

妳會看到服務端發來得數據。

那麽基本的點對點通信就沒問題了。只要兩臺機器同時包含服務端和客戶端,就可以互相通信了。

當然,妳也可以將服務端和客戶端分開做,專門壹個服務器負責用戶登錄和轉發消息。

流程如下:

A客戶端發登錄消息-----》服務器

服務器驗證發送用戶消息----》客戶端

A客戶端想發消息給B客戶端----》先發給服務端

服務器得到消息查詢B客戶端IP並轉發消息。(或者B客戶端循環發消息詢問服務器有無消息)

通信結束。

  • 上一篇:米粒造句-用米粒造句
  • 下一篇:單片機AT89S52的p0,p1,p3管腳都是幹什麽的?
  • copyright 2024編程學習大全網