socket通訊

Socket通訊

一、函數
socket:創建一個socket
bind:綁定IP地址和端口號到docket
connect:與服務器建立連接
listen:設置服務器能處理的最大連接要求
accept:等待來自客戶端的socket連接請求
send:發送數據
recv:接收數據

二、TCP
1.基於TCP服務器
1.創建一個socket,函數socket()
2.綁定IP地址端口等信息到socket上,函數bind()
3.設置允許的最大連接數,函數listen()
4.等待來自客戶端的連接請求,函數accept()
5.收發數據,用send和recv或者read和write
6.關閉網絡連接

2.基於TCP客戶端
1.創建一個socket,函數socket
2.設置要連接的服務器的IP地址和端口屬性
3.連接服務器,函數connect
4.收發數據,用send、recv或read、write函數
5.關閉網絡連接

3.基於TCP的通訊模型
服務器
socket
  |
bind
  |
listen    客戶機
  |       |
accept    socket
  |       |
阻塞等待用戶數  <--- 建立連接 ---  connect
  |       |
read <--- 請求數據 ---    write
  |       |
處理服務       |
  |       |
write --- 應答數據 --->     read
  |       |

close      close


三、UDP
1.基於UDP服務器
1.創建一個socket,函數socket
2.綁定IP地址,端口等信息到docket,函數bind
3.循環接收數據,函數recvfrom
4.關閉網絡連接

2.基於UDP客戶端
1.創建一個socket,函數socket
2.綁定IP地址,端口等信息到socket上,函數bind
3.設置對方的IP地址和端口等屬性
4.發送數據,函數sendto
5.關閉網絡連接

3.基於UDP通訊模型
服務器
socket
  |   客戶機
bind   socket
  |       |
readfrom     bind
  |       |
阻塞等待客戶數  <--- 請求服務 ---  sendto 
  |       |
處理服務請求      |
  |       |
sendto --- 應答服務 --->   readfrom
  |       |
close     close

四、循環、併發服務器
循環服務器:服務器同一時刻只能響應一個客戶端
併發服務器:服務器同一時刻能響應多個客戶端

TCP服務器如果有一個客戶端佔住不放,其他的客戶機都不能工作,所以TCP一般很少使用循環服務器

TCP併發服務器
socket
bind
listen
while(1){
accept
if(fork() == 0){
process()
close
exit
}
}

五、例子
1.TCP服務器
//TCP Service
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include<sys/wait.h>
#include <tcl.h>
#include <unistd.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
if(argc != 2)
{
//printf("Usage: UDPClient ...\n");
//exit(1);
}

struct sockaddr_in client;
struct sockaddr_in sock;
sock.sin_family = AF_INET;
sock.sin_port = 3490;
//自動填本機ip
sock.sin_addr.s_addr = INADDR_ANY;
bzero(&(sock.sin_zero), 8);

int sockid = socket(AF_INET, SOCK_STREAM, 0);
if(sockid == -1)
{
printf("socket error! line = %d\n", __LINE__);
return -1;
}

int nBind = bind(sockid, (struct sockaddr *)&sock, sizeof(sock));
if (nBind == -1)
{
printf("bind error! line = %d\n", __LINE__);
return -1;
}

int nListenRe = listen(sockid, 10);//listen的請求接收隊列長度
if (nListenRe == -1)
{
printf("listen error! line = %d\n", __LINE__);
return -1;
}

char cRecvChar[64] = "\0";
ssize_t nRecvSize;
while(1)
{
int size = sizeof(struct sockaddr_in);
int nAccept = accept(sockid, (struct sockaddr*)&client, &size);
if (nAccept == -1)
{
printf("accept error! line = %d\n", __LINE__);
continue;
}
else
{
//printf("get connection from %s\n", inet_ntoa(client.sin_addr));
while(1)
{
nRecvSize = recv(nAccept, (void *)cRecvChar, 64, 0);
if (nRecvSize <= 0)
{
printf("recv Error!\n");
}
else
{
printf("get connection from %s\n", inet_ntoa(client.sin_addr));
printf("recv byte = %s\n", cRecvChar);
}
sleep(1);
}
}
sleep(1);
close(nAccept);
}
close(sockid);
}

2.TCP客戶端
//TCP Client
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include<sys/wait.h>
#include <tcl.h>
#include <unistd.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
if(argc != 2)
{
printf("Usage: UDPClient ...\n");
return -1;
}

struct sockaddr_in sock;
sock.sin_family = AF_INET;
sock.sin_port = 3490;
sock.sin_addr.s_addr = inet_addr("127.0.0.1");

struct sockaddr_in client_sock;
client_sock.sin_family = AF_INET;
client_sock.sin_addr.s_addr = htonl(INADDR_ANY);
client_sock.sin_port = 0;
//memset(sock.size_zero, 0, sizeof(sock.size_zero));

int sockid = socket(AF_INET, SOCK_STREAM, 0);
if(sockid == -1)
{
printf("socket error! line = %d\n", __LINE__);
return -1;
}

int nBindID = bind(sockid, (struct sockaddr*)&client_sock, sizeof(struct sockaddr_in));
if(nBindID == -1)
{
printf("bind error! line = %d\n", __LINE__);
return -1;
}

int nConID = connect(sockid, (struct sockaddr *)&sock, sizeof(sock));
if (nConID == -1)
{
printf("connect error! line = %d\n", __LINE__);
return -1;
}

char cSendChar[64] = "hello";
ssize_t nSendSize;
while(1)
{
nSendSize = send(sockid, (void *)cSendChar, strlen(cSendChar), 0);
if (nSendSize)
{
printf("send %d byte ok!\n", nSendSize);
}
else
{
printf("send Error!\n");
}

//char msg[64];
//recv(sockid, msg, 64, 0);
//printf("client recv msg = %s\n", msg);

sleep(2);
}

close(sockid);
}

3.UDP服務器
//UDP Service
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include<sys/wait.h>
#include <tcl.h>
#include <unistd.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
if(argc != 2)
{
//printf("Usage: UDPClient ...\n");
//exit(1);
}

struct sockaddr_in client;
struct sockaddr_in sock;
sock.sin_family = AF_INET;
sock.sin_port = 3490;
sock.sin_addr.s_addr = INADDR_ANY;
//memset(sock.size_zero, 0, sizeof(sock.size_zero));

int sockid = socket(AF_INET, SOCK_DGRAM, 0);
if(sockid == -1)
{
printf("socket error! line = %d\n", __LINE__);
return -1;
}

int nBind = bind(sockid, (struct sockaddr *)&sock, sizeof(sock));
if (nBind == -1)
{
printf("bind error! line = %d\n", __LINE__);
return -1;
}

char cRecvChar[64] = "\0";
ssize_t nRecvSize;
int size;
while(1)
{
nRecvSize = recvfrom(sockid, (void *)cRecvChar, 64, 0, (struct sockaddr *)&client, &size);
if (nRecvSize == 0)
{
printf("recv Error!\n");
}
else
{
printf("recv %d byte ok!\n", nRecvSize);
printf("recv byte = %s\n", cRecvChar);
}
sleep(2);
}

close(sockid);
}

4.UDP客戶端
//UDP Client
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include<sys/wait.h>
#include <tcl.h>
#include <unistd.h>
#include <arpa/inet.h>

int main(int argc, char **argv)
{
if(argc != 2)
{
printf("Usage: UDPClient ...\n");
return -1;
}

struct sockaddr_in sock;
sock.sin_family = AF_INET;
sock.sin_port = 3490;
sock.sin_addr.s_addr = inet_addr("127.0.0.1");
//memset(sock.size_zero, 0, sizeof(sock.size_zero));

int sockid = socket(AF_INET, SOCK_DGRAM, 0);
if(sockid == -1)
{
printf("socket error! line = %d\n", __LINE__);
return -1;
}

int nBindID = bind(sockid, (struct sockaddr*)&sock, sizeof(struct sockaddr_in));
if(nBindID == -1)
{
printf("bind error! line = %d\n", __LINE__);
return -1;
}

char cSendChar[64] = "hello";
ssize_t nSendSize;
while(1)
{
nSendSize = sendto(sockid, (void *)cSendChar, 64, 0, (struct sockaddr *)&sock, sizeof(sock));
if (nSendSize)
{
printf("send %d byte ok!\n", nSendSize);
}
else
{
printf("send Error!\n");
}
sleep(2);
}

close(sockid);
}



























































發佈了40 篇原創文章 · 獲贊 3 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章