套接字程式設計
套接字程式設計
在TCP/IP協定中,IP位址+端口号—->唯一的辨別一個程序
IP位址+端口号就是套接字,套接字程式設計就是兩個程序分别有自己的socket,這兩個程序的socket組成一對,就唯一的辨別了這兩個程序之間的連接配接,然後就可以進行互相的通信了
1.實作一個用戶端給伺服器發送消息,伺服器的作用就是回顯用戶端發給自己的消息
1.實作一個用戶端給伺服器發送消息,伺服器的作用就是回顯用戶端發給自己的消息
server.c (伺服器端)
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
#define ERR_EXIT(m)\
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}while()
void Usage(){
printf("Usage ./server [ip] [port]\n");
return;
}
int main(int argc,char*argv[]){
if(!=argc){
Usage();
return ;
}
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_addr.s_addr=inet_addr(argv[]);
local.sin_port=htons(atoi(argv[]));
//1.建立套接字
int sockfd= socket(AF_INET,SOCK_DGRAM,);
if(sockfd<)
ERR_EXIT("socket");
//2.進行綁定
int ret= bind(sockfd,(sockaddr*)&local,sizeof(local));
if(ret<)
ERR_EXIT("bind");
//3.循環的把用戶端發送的資料,給用戶端發送回去
char buf[]={};
sockaddr_in client;
while(){
socklen_t len=sizeof(client);
ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-,,\
(sockaddr*)&client,&len);
if(s>) {
buf[s]=;
printf("client [%s: %d] say:> %s\n",inet_ntoa(client.sin_addr),\
ntohs(client.sin_port),buf);
sendto(sockfd,buf,strlen(buf),,\
(sockaddr*)&client,sizeof(client));
}
}
return ;
}
client.c(客戶機端)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
#define ERR_EXIT(m)\
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}while()
void Usage(){
printf("Usage ./client [ip] [port]\n");
return;
}
int main(int argc,char* argv[]){
if(!=argc){
Usage();
return ;
}
sockaddr_in server;
server.sin_family=AF_INET;
server.sin_addr.s_addr=inet_addr(argv[]);
server.sin_port=htons(atoi(argv[]));
//1.建立套接字
int sockfd=socket(AF_INET,SOCK_DGRAM,);
if(sockfd<)
ERR_EXIT("socket");
//2.從鍵盤循環的讀取資料
char buf[]={};
while(){
socklen_t len=sizeof(server);
printf("please enter:> ");
fflush(stdout);
ssize_t read_size= read(,buf,sizeof(buf)-);
//3.把讀到的資料發送給伺服器
if(read_size>){
buf[read_size-] = ;//read是讀到換行結束的,故會多讀一個字元
sendto(sockfd,buf,strlen(buf),,\
(sockaddr*)&server,sizeof(server));
ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-,,\
(sockaddr*)&server,&len);
//4.把伺服器發送的資料顯示到螢幕上
if(s>){
buf[s]=;
printf("serevr echo:> %s\n",buf);
}
}
}
return ;
}
運作結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TP35UNj1mYwBnMaVnRHFmNk1mYoJlMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DO5cTNzUzMwEDNxUDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
2.實作一個用戶端與伺服器之間的通信,用戶端給伺服器發送消息,伺服器的作用是接收到用戶端發給自己的資訊,再給用戶端回複消息
2.實作一個用戶端與伺服器之間的通信,用戶端給伺服器發送消息,伺服器的作用是接收到用戶端發給自己的資訊,再給用戶端回複消息
server.c (伺服器端)
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
#define ERR_EXIT(m)\
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}while()
void Usage(){
printf("Usage ./server [ip] [port]\n");
return;
}
int main(int argc,char*argv[]){
if(!=argc){
Usage();
return ;
}
sockaddr_in local;
local.sin_family=AF_INET;
local.sin_addr.s_addr=inet_addr(argv[]);
local.sin_port=htons(atoi(argv[]));
//1.建立套接字
int sockfd= socket(AF_INET,SOCK_DGRAM,);
if(sockfd<)
ERR_EXIT("socket");
//2.進行綁定
int ret= bind(sockfd,(sockaddr*)&local,sizeof(local));
if(ret<)
ERR_EXIT("bind");
//3.循環的進行用戶端與伺服器之間的通信
char buf[]={};
sockaddr_in client;
while(){
socklen_t len=sizeof(client);
//接收用戶端發送的資料,并把發送的資料輸出到螢幕
ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-,,\
(sockaddr*)&client,&len);
if(s>) {
buf[s]=;
printf("client [%s: %d] say:> %s\n",inet_ntoa(client.sin_addr),\
ntohs(client.sin_port),buf);
//給用戶端發送消息
memset(buf,,sizeof(buf));
printf("please enter:> ");
fflush(stdout);
ssize_t read_size = read(,buf,sizeof(buf)-);
printf("please wait......\n");
if(read_size>){
buf[read_size-]=;
sendto(sockfd,buf,strlen(buf),,\
(sockaddr*)&client,sizeof(client));
}
}
}
return ;
}
client.c(客戶機端)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
#define ERR_EXIT(m)\
do\
{\
perror(m);\
exit(EXIT_FAILURE);\
}while()
void Usage(){
printf("Usage ./client [ip] [port]\n");
return;
}
int main(int argc,char* argv[]){
if(!=argc){
Usage();
return ;
}
sockaddr_in server;
server.sin_family=AF_INET;
server.sin_addr.s_addr=inet_addr(argv[]);
server.sin_port=htons(atoi(argv[]));
//1.建立套接字
int sockfd=socket(AF_INET,SOCK_DGRAM,);
if(sockfd<)
ERR_EXIT("socket");
//2.從鍵盤循環的讀取資料
char buf[]={};
while(){
socklen_t len=sizeof(server);
printf("please enter:> ");
fflush(stdout);
ssize_t read_size= read(,buf,sizeof(buf)-);
//3.把讀到的資料發送給伺服器
if(read_size>){
buf[read_size-] = ;//read是讀到換行結束的,故會多讀一個字元
sendto(sockfd,buf,strlen(buf),,\
(sockaddr*)&server,sizeof(server));
printf("please wait......\n");
ssize_t s=recvfrom(sockfd,buf,sizeof(buf)-,,\
(sockaddr*)&server,&len);
//4.把伺服器發送的資料顯示到螢幕上
if(s>){
buf[s]=;
printf("serevr say:> %s\n",buf);
}
}
}
return ;
}
運作結果:
IP位址
0:表示伺服器可關聯任意的位址
127.0.0.1:此IP位址是環回位址,是留給使用者使用的
相關函數的用法請參考部落格:
https://blog.csdn.net/dangzhangjing97/article/details/80280770
IP位址和端口請參考部落格:
https://blog.csdn.net/dangzhangjing97/article/details/80280254