套接字編程實例
『壹』 套接字是什麼
套接字(socket)是一個抽象層,應用程序可以通過它發送或接收數據,可對其進行像對文件一樣的打開、讀寫和關閉等操作。套接字允許應用程序將I/O插入到網路中,並與網路中的其他應用程序進行通信。網路套接字是IP地址與埠的組合。
總之,套接字Socket=(IP地址:埠號),套接字的表示方法是點分十進制的IP地址後面寫上埠號,中間用冒號或逗號隔開。每一個傳輸層連接唯一地被通信兩端的兩個端點(即兩個套接字)所確定。
(1)套接字編程實例擴展閱讀
Socket最初是加利福尼亞大學Berkeley分校為Unix系統開發的網路通信介面。後來隨著TCP/IP網路的發展,Socket成為最為通用的應用程序介面,也是在Internet上進行應用開發最為通用的API。
Windows系統流行起來之後,由Microsoft聯合了其他幾家公司在Berkeley Sockets的基礎之上進行了擴充,共同制定了一套Windows下的網路編程介面,即Windows Sockets規范。
Windows Sockets規范是一套開放的、支持多種協議的Windows下的網路編程介面,包括1.1版和2.0版兩個版本。
參考資料來源:網路-套接字
『貳』 基於Linux的遠程指令系統(使用udp而不是tcp)
一. Linux下UDP編程框架
使用UDP進行程序設計可以分為客戶端和伺服器端兩部分。
1.伺服器端程序包括:
? 建立套接字
? 將套接字地址結構進行綁定
? 讀寫數據
? 關閉套接字
2.客戶端程序包括:
? 建立套接字
? 讀寫數據
? 關閉套接字
3.伺服器端和客戶端程序之間的差別
伺服器端和客戶端兩個流程之間的主要差別在於對地址的綁定函數(bind()函數),而客戶端可以不用進行地址和埠的綁定操作。
二.Linux中UDP套接字函數
從圖可知,UDP協議的服務端程序設計的流程分為套接字建立,套接字與地址結構進行綁定,收發數據,關閉套接字;客戶端程序流程為套接字建立,收發數據,關閉套接字等過程。它們分別對應socket(),bind(),sendto(),recvfrom(),和close()函數。
網路程序通過調用socket()函數,會返回一個用於通信的套接字描述符。Linux應用程序在執行任何形式的I/O操作的時候,程序是在讀或者寫一個文件描述符。因此,可以把創建的套接字描述符看成普通的描述符來操作,並通過讀寫套接字描述符來實現網路之間的數據交流。
1. socket
1> 函數原型:
int socket(int domain,int type,int protocol)
2> 函數功能:
函數socket()用於創建一個套接字描述符。
3> 形參:
? domain:用於指定創建套接字所使用的協議族,在頭文件
中定義。
常見的協議族如下:
AF_UNIX:創建只在本機內進行通信的套接字。
AF_INET:使用IPv4 TCP/IP協議
AF_INET6:使用IPv6 TCP/IP協議
說明:
AF_UNIX只能用於單一的UNIX系統進程間通信,而AF_INET是針對Interne的,因而可以允許在遠程主機之間通信。一般把它賦為AF_INET。
? type:指明套接的類型,對應的參數如下
SOCK_STREAM:創建TCP流套接字
SOCK_DGRAM:創建UDP數據報套接字
SOCK_RAW:創建原始套接字
? protocol:
參數protocol通常設置為0,表示通過參數domain指定的協議族和參數type指定的套接字類型來確定使用的協議。當為原始套接字時,系統無法唯一的確定協議,此時就需要使用使用該參數指定所使用的協議。
4> 返回值:執行成功後返回一個新創建的套接字;若有錯誤發生則返回一個-1,錯誤代碼存入errno中。
5> 舉例:調用socket函數創建一個UDP套接字
int sock_fd;
sock_fd = socket(AF_INET,SOCK_DGRAM,0);
if(sock_fd < 0){
perror(「socket」);
exit(1);
}
2. bind
1> 函數原型:
int bind(int sockfd,struct sockaddr *my_addr,socklen_taddrlen)
2> 函數功能
函數bind()的作用是將一個套接字文件描述符與一個本地地址綁定在一起。
3> 形參:
? sockfd:sockfd是調用socket函數返回的文件描述符;
? addrlen是sockaddr結構的長度。
? my_addr: 是一個指向sockaddr結構的指針,它保存著本地套接字的地址(即埠和IP地址)信息。不過由於系統兼容性的問題,一般不使用這個結構,而使用另外一個結構(struct sockaddr_in)來代替
4> 套接字地址結構:
(1)structsockaddr:
結構struct sockaddr定義了一種通用的套接字地址,它在
Linux/socket.h 中定義。
struct sockaddr{
unsigned short sa_family;/*地址類型,AF_XXX*/
char sa_data[14];/*14位元組的協議地址*/
}
a. sin_family:表示地址類型,對於使用TCP/IP協議進行的網路編程,該值只能是AF_INET.
b. sa_data:存儲具體的協議地址。
(2)sockaddr_in
每種協議族都有自己的協議地址格式,TCP/IP協議組的地址格式為結構體struct sockaddr_in,它在netinet/in.h頭文件中定義。
struct sockaddr_in{
unsigned short sin_family;/*地址類型*/
unsigned short sin_port;/*埠號*/
struct in_addr sin_addr;/*IP地址*/
unsigned char sin_zero[8];/*填充位元組,一般賦值為0*/
}
a. sin_family:表示地址類型,對於使用TCP/IP協議進行的網路編程,該值只能是AF_INET.
b. sin_port:是埠號
c. sin_addr:用來存儲32位的IP地址。
d. 數組sin_zero為填充欄位,一般賦值為0.
e. structin_addr的定義如下:
struct in_addr{
unsignedlong s_addr;
}
結構體sockaddr的長度為16位元組,結構體sockaddr_in的長度為16位元組。可以將參數my_addr的sin_addr設置為INADDR_ANY而不是某個確定的IP地址就可以綁定到任何網路介面。對於只有一IP地址的計算機,INADDR_ANY對應的就是它的IP地址;對於多宿主主機(擁有多個網卡),INADDR_ANY表示本伺服器程序將處理來自所有網路介面上相應埠的連接請求
5> 返回值:
函數成功後返回0,當有錯誤發生時則返回-1,錯誤代碼存入errno中。
6>舉例:調用socket函數創建一個UDP套接字
struct sockaddr_in addr_serv,addr_client;/*本地的地址信息*/
memset(&serv_addr,0,sizeof(struct sockaddr_in));
addr_serv.sin_family = AF_INET;/*協議族*/
addr_serv.sin_port = htons(SERV_PORT);/*本地埠號*/
addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); /*任意本地地址*/
/*套接字綁定*/
if(bind(sock_fd,(struct sockaddr *)&addr_serv),sizeof(structsockaddr_in)) <0)
{
perror(「bind」);
exit(1);
}
3.close
1>函數原型:
int close(intfd);
2>函數功能:
函數close用來關閉一個套接字描述符。
3>函數形參:
? 參數fd為一個套接字描述符。
4>返回值:
執行成功返回0,出錯則返回-1.錯誤代碼存入errno中。
說明:
以上三個函數中,前兩個要包含頭文件
#include
#include
後一個包含:
#include
4.sendto
1>函數原型:
#include
#include
ssize_t sendo(ints,const void *msg,size_t len,int flags,const struct sockaddr *to,socklen_ttolen);
2>函數功能:
向目標主機發送消息
3>函數形參:
? s:套接字描述符。
? *msg:發送緩沖區
? len:待發送數據的長度
? flags:控制選項,一般設置為0或取下面的值
(1)MSG_OOB:在指定的套接字上發送帶外數據(out-of-band data),該類型的套接字必須支持帶外數據(eg:SOCK_STREAM).
(2)MSG_DONTROUTE:通過最直接的路徑發送數據,而忽略下層協議的路由設置。
? to:用於指定目的地址
? tolen:目的地址的長度。
4>函數返回值:
執行成功後返回實際發送數據的位元組數,出錯返回-1,錯誤代碼存入errno中。
5>函數舉例:
char send_buf[BUFFERSIZE];
struct sockaddr_in addr_client;
memset(&addr_client,0,sizeof(struct sockaddr_in));
addr_client.sin_family = AF_INET;
addr_client.sin_port = htons(DEST_PORT);
if(inet_aton(「172.17.242.131」,&addr_client.sin_addr)<0){
perror(「inet_aton」);
exit(1);
}
if(sendto(sock_fd,send_buf,len,0,(strut sockaddr*)&addr_client,sizeof(struct sockaddr_in)) <0){
perror(「sendto」);
exit(1);
}
5.recvfrom
1>函數原型:
#include
#include
ssize_t recvfrom(int s,void *buf,size_t len,intflags,struct sockaddr *from,socklen_t *fromlen);
2>函數功能:接收數據
3>函數形參:
? int s:套接字描述符
? buf:指向接收緩沖區,接收到的數據將放在這個指針所指向的內存空間。
? len:指定了緩沖區的大小。
? flags:控制選項,一般設置為0或取以下值
(1)MSG_OOB:請求接收帶外數據
(2)MSG_PEEK:只查看數據而不讀出
(3)MSG_WAITALL:只在接收緩沖區時才返回。
? *from:保存了接收數據報的源地址。
? *fromlen:參數fromlen在調用recvfrom前為參數from的長度,調用recvfrom後將保存from的實際大小。
4>函數返回值:
執行成功後返回實際接收到數據的位元組數,出錯時則返回-1,錯誤代碼存入errno中。
5>函數實例:
char recv_buf[BUFFERSIZE];
struct sockaddr_in addr_client;
int src_len;
src_len = sizeof(struct sockaddr_in);
int src_len;
src_len = sizeof(struct sockaddr_in);
if(recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(structsockaddr *)&src_addr,&src_len)<0){
perror(「again_recvfrom」);
exit(1);
}
三.UDP編程實例
客戶端向伺服器發送字元串Hello tiger,伺服器接收到數據後將接收到字元串發送回客戶端。
1.伺服器端程序
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9
10 #define SERV_PORT 3000
11
12 int main()
13 {
14 int sock_fd; //套接子描述符號
15 int recv_num;
16 int send_num;
17 int client_len;
18 char recv_buf[20];
19 struct sockaddr_in addr_serv;
20 struct sockaddr_in addr_client;//伺服器和客戶端地址
21 sock_fd = socket(AF_INET,SOCK_DGRAM,0);
22 if(sock_fd < 0){
23 perror("socket");
24 exit(1);
25 } else{
26
27 printf("sock sucessful\n");
28 }
29 //初始化伺服器斷地址
30 memset(&addr_serv,0,sizeof(struct sockaddr_in));
31 addr_serv.sin_family = AF_INET;//協議族
32 addr_serv.sin_port = htons(SERV_PORT);
33 addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);//任意本地址
34
35 client_len = sizeof(struct sockaddr_in);
36 /*綁定套接子*/
37 if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0 ){
38 perror("bind");
39 exit(1);
40 } else{
41
42 printf("bind sucess\n");
43 }
44 while(1){
45 printf("begin recv:\n");
46 recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);
47 if(recv_num < 0){
48 printf("bad\n");
49 perror("again recvfrom");
50 exit(1);
51 } else{
52 recv_buf[recv_num]='\0';
53 printf("recv sucess:%s\n",recv_buf);
54 }
55 printf("begin send:\n");
56 send_num = sendto(sock_fd,recv_buf,recv_num,0,(struct sockaddr *)&addr_client,client_len);
57 if(send_num < 0){
58 perror("sendto");
59 exit(1);
60 } else{
61 printf("send sucessful\n");
62 }
63 }
64 close(sock_fd);
65 return 0;
66 }
2.客戶端程序
1 #include
2 #include
3 #include
4 #include
5 #include
6
7 #include
8 #include
9 #include
10
11 #define DEST_PORT 3000
12 #define DSET_IP_ADDRESS "192.168.1.103"
13
14 int main()
15 {
16 int sock_fd;/*套接字文件描述符*/
17 int send_num;
18 int recv_num;
19 int dest_len;
20 char send_buf[20]={"hello tiger"};
21 char recv_buf[20];
22 struct sockaddr_in addr_serv;/*服務端地址,客戶端地址*/
23
24 sock_fd = socket(AF_INET,SOCK_DGRAM,0);//創建套接子
25 //初始化伺服器端地址
26 memset(&addr_serv,0,sizeof(addr_serv));
27 addr_serv.sin_family = AF_INET;
28 addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
29 addr_serv.sin_port = htons(DEST_PORT);
30
31 dest_len = sizeof(struct sockaddr_in);
32 printf("begin send:\n");
33 send_num = sendto(sock_fd,send_buf,sizeof(send_buf),0,(struct sockaddr *)&addr_serv,dest_len);
34 if(send_num < 0){
35 perror("sendto");
36 exit(1);
37 } else{
38
39 printf("send sucessful:%s\n",send_buf);
40 }
41 recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_serv,&dest_len);
42 if(recv_num <0 ){
43
44 perror("recv_from");
45 exit(1);
46 } else{
47 printf("recv sucessful\n");
48 }
49 recv_buf[recv_num]='\0';
50 printf("the receive:%s\n",recv_buf);
51 close(sock_fd);
52 return 0;
53 }
『叄』 UDP和Socket通信步驟
這是在網上找到的,希望對你有所幫助。
sockets(套接字)編程有三種,流式套接字(SOCK_STREAM),數據報套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);
WINDOWS環境下TCP/UDP編程步驟:
1. 基於TCP的socket編程是採用的流式套接字。
在這個程序中,將兩個工程添加到一個工作區。要鏈接一個ws2_32.lib的庫文件。
伺服器端編程的步驟:
1:載入套接字型檔,創建套接字(WSAStartup()/socket());
2:綁定套接字到一個IP地址和一個埠上(bind());
3:將套接字設置為監聽模式等待連接請求(listen());
4:請求到來後,接受連接請求,返回一個新的對應於此次連接的套接字(accept());
5:用返回的套接字和客戶端進行通信(send()/recv());
6:返回,等待另一連接請求;
7:關閉套接字,關閉載入的套接字型檔(closesocket()/WSACleanup())。
伺服器端代碼如下:
#include <stdio.h>
#include <Winsock2.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[50];
sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[50];
recv(sockConn,recvBuf,50,0);
printf("%s\n",recvBuf);
closesocket(sockConn);
}
}
客戶端編程的步驟:
1:載入套接字型檔,創建套接字(WSAStartup()/socket());
2:向伺服器發出連接請求(connect());
3:和伺服器端進行通信(send()/recv());
4:關閉套接字,關閉載入的套接字型檔(closesocket()/WSACleanup())。
客戶端的代碼如下:
#include <stdio.h>
#include <Winsock2.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[50];
recv(sockClient,recvBuf,50,0);
printf("%s\n",recvBuf);
send(sockClient,"hello",strlen("hello")+1,0);
closesocket(sockClient);
WSACleanup();
}
2.基於UDP的socket編程是採用的數據報套接字。
在這個程序中,將兩個工程添加到一個工作區。同時還要鏈接一個ws2_32.lib的庫文件。
伺服器端編程的步驟:
1:載入套接字型檔,創建套接字(WSAStartup()/socket());
2:綁定套接字到一個IP地址和一個埠上(bind());
3:等待和接收數據(sendto()/recvfrom());
4:關閉套接字,關閉載入的套接字型檔(closesocket()/WSACleanup())。
伺服器端代碼如下:
#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(7003);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf[50];
SOCKADDR addrClient;
int len=sizeof(SOCKADDR);
recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)&addrClient,&len);
printf("%s\n",recvBuf);
closesocket(sockSrv);
WSACleanup();
}
對於基於UDP的socket客戶端來說,要進行如下步驟:
1:創建一個套接字(socket);
2:向伺服器發送數據(sendto);
3:關閉套接字;
代碼如下:
#include <winsock2.h>
#include <stdio.h>
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addrClient.sin_family=AF_INET;
addrClient.sin_port=htons(8889);
SOCKADDR_IN addrSrv;
sendto(sockClient,"hi",3,0,(SOCKADDR*)&addrClient,sizeof(SOCKADDR));
}
LINUX環境下TCP/UDP編程步驟:
TCP編程步驟:
一. 服務端:
1.socket(int domain,int type,int protocol):建立套接字;
2 .bind(int sockid,struct sockaddr *addrp,socklen_t addrlen):把本機地址和埠跟上一步建立的socket綁定在一起;
3.listen(int sockid,int qsize):監聽某套接字;
4.fd=accept(int sockid,struct sockaddr *callerid,socklen_t *addrlenp):等待某套接字接收信息;
5.recv(int fd,void *buf,size_t nbytes,int flags):從套接字接收數據;
6.close(fd) 和close(sockid)
二.客戶端:
1. socket():建立套接字;
2.connect(int sockid,struct sockaddr *serv_addrp,socklen_t addrlen):連接到伺服器;
3. send(int sockfd,const void *buf,size_t nbytes,int flags):發送數據到伺服器.
4. close(sockid);
UDP編程步驟:
一,服務端:
1. socket():同上;
2. bind():同上;
3. recvfrom(int sockfd,void*buff,size_t nbytes,int flags,struct sockaddr*from,socklen_t*addrlen):在套接字口接收數據,並且記錄下接收到的數據來源;一定要注意這里的參數addrlen,它不僅是函數的輸出,也是函數的輸入!所以要在調用該函數之前對addrlen賦值sizeof(struct sockaddr)。否則返回的地址from將會出錯!
4. close(sockfd);
二. 客戶端:
1. socket();同上;
2. sendto(int sockfd,const void*buff,size_t nbytes,int flags,const struct sockaddr*to,socklen_t addrlen):往指定的地址發送數據;
3. close(sockfd);
『肆』 Socket編程
最近也在學 還有一個自己寫的C++聊天程序 有點大 下面是C寫的
sockets(套接字)編程有三種,流式套接字(SOCK_STREAM),數據報套接字 (SOCK_DGRAM),原始套接字(SOCK_RAW);基於TCP的socket編程是採用的流式套接字(SOCK_STREAM)。基於UDP采 用的數據報套接字(SOCK_DGRAM).
1.TCP流式套接字的編程步驟
在使用之前須鏈接庫函數:工程->設置->Link->輸入ws2_32.lib,OK!
伺服器端程序:
1、載入套接字型檔
2、創建套接字(socket)。
3、將套接字綁定到一個本地地址和埠上(bind)。
4、將套接字設為監聽模式,准備接收客戶請求(listen)。
5、等待客戶請求到來;當請求到來後,接受連接請求,返回一個新的對應於此次連接的套接字(accept)。
6、用返回的套接字和客戶端進行通信(send/recv)。
7、返回,等待另一客戶請求。
8、關閉套接字。
客戶端程序:
1、載入套接字型檔
2、創建套接字(socket)。
3、向伺服器發出連接請求(connect)。
4、和伺服器端進行通信(send/recv)。
5、關閉套接字
伺服器端代碼如下:
#include <Winsock2.h>//加裁頭文件
#include <stdio.h>//載入標准輸入輸出頭文件
void main()
{
WORD wVersionRequested;//版本號
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );//1.1版本的套接字
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}//載入套接字型檔,加裁失敗則返回
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}//如果不是1.1的則退出
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);//創建套接字(socket)。
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//轉換Unsigned short為網路位元組序的格式
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
//將套接字綁定到一個本地地址和埠上(bind)
listen(sockSrv,5);//將套接字設為監聽模式,准備接收客戶請求(listen)。
SOCKADDR_IN addrClient;//定義地址族
int len=sizeof(SOCKADDR);//初始化這個參數,這個參數必須被初始化
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);//accept的第三個參數一定要有初始值。
//等待客戶請求到來;當請求到來後,接受連接請求,返回一個新的對應於此次連接的套接字(accept)。
//此時程序在此發生阻塞
char sendBuf[100];
sprintf(sendBuf,"Welcome %s to http://www.sunxin.org",
inet_ntoa(addrClient.sin_addr));
//用返回的套接字和客戶端進行通信(send/recv)。
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf[100];
recv(sockConn,recvBuf,100,0);
printf("%s\n",recvBuf);
closesocket(sockConn);//關閉套接字。等待另一個用戶請求
}
}
客戶端代碼如下:
#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);創建套接字(socket)。
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));向伺服器發出連接請求(connect)。
char recvBuf[100];和伺服器端進行通信(send/recv)。
recv(sockClient,recvBuf,100,0);
printf("%s\n",recvBuf);
send(sockClient,"This is lisi",strlen("This is lisi")+1,0);
closesocket(sockClient);關閉套接字。
WSACleanup();//必須調用這個函數清除參數
}