socket編程

一、套接字相關
1、socket是一種應用程序訪問通信協議的操作系統調用
2、socket存在於通信區域中,通信區域也叫地址族,主要用於將通過socket通信的進程的共有特性綜合在一起。socket通常只與同一區域的套接字交換數據。
3、windows socket只支持一個通信區域:網際域(AF_INET),這個域被使用網際協議簇通信的進程使用。

二、套接字的類型
1、流式套接字(SOCK_STREAM):這個是基於TCP協議的,面向連接,可靠,數據無差錯、無重複發送,按發送順序接收
2、數據報式套接字(SOCK_DGRAM):這個是基於UDP協議的,無連接,不提供無錯保證,數據可能丟失或重複,接收順序混亂
3、原始套接字(SOCK_RAW)

三、基於TCP的socket編程步驟
服務器端:
1、用socket函數創建套接字
2、用bind函數將套接字綁定到一個本地地址和一個端口上
3、用listen函數將套接字設爲監聽模式準備接收客戶請求
4、用accept函數等待用戶請求的到來;當請求到來後,接受連接請求,返回一個新的對應於此連接的套接字
5、用返回的套接字和客戶端進行通信,send/rev函數
6、返回,等待另一個客戶請求
7、關閉套接字

#include <WinSock2.h> #include <stdio.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return; } SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr =htonl(INADDR_ANY); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000); bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); listen(sockSrv, 5); SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); while(1) { SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient,&len); char sendBuf[100]; sprintf(sendBuf, "Welcome %s to lcqidbzt's blog", inet_ntoa(addrClient.sin_addr)); send(sockConn, sendBuf, strlen(sendBuf)+1, 0); char recvBuf[100]; recv(sockConn, recvBuf, 100, 0); printf("%s\n",recvBuf); closesocket(sockConn); }


客戶端:
1、用socket函數創建套接字
2、用connect函數向服務器發出連接請求
3、用send/rev函數和服務器端進行通信
4、關閉套接字

#include <WinSock2.h> #include <stdio.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return; } SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000); connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); char recvBuf[100]; recv(sockClient, recvBuf, 100, 0); printf("%s\n",recvBuf); send(sockClient, "This is zhangshan", strlen("This is zhangshan")+1, 0); closesocket(sockClient); WSACleanup(); }



四、基於UDP的socket編程
服務器端:
1、用socket函數創建套接字
2、用bind函數將套接字綁定到一個本地地址和端口上
3、用recvfrom函數等待接收數據
4、關閉套接字

#include <WinSock2.h> #include <stdio.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return; } SOCKET sockSrv = socket(AF_INET, SOCK_DGRAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000); bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); char recvBuf[100]; recvfrom(sockSrv, recvBuf, 100, 0, (SOCKADDR*)&addrClient, &len); printf("%s\n",recvBuf); closesocket(sockSrv); WSACleanup(); }


客戶端:
1、用socket函數創建套接字
2、用sendto函數向服務器發送數據
3、關閉套接字

#include <WinSock2.h> #include <stdio.h> void main() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD(1, 1); err = WSAStartup(wVersionRequested, &wsaData); if (err != 0) { return; } if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return; } SOCKET sockClient = socket(AF_INET, SOCK_DGRAM, 0); SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000); char sendBuf[100]; sendto(sockClient, "hello", strlen("hello")+1, 0 ,(SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); closesocket(sockClient); WSACleanup(); }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章