linux環境下網路程式設計
阿新 • • 發佈:2018-12-22
參考
https://www.cnblogs.com/diligenceday/p/6241021.html
https://blog.csdn.net/baidu_36649389/article/details/79081770
http://www.cnblogs.com/wangcq/p/3520400.html
socket是網路程序的PID,由執行程序的計算機的IP地址和程序使用的埠組成。
非同步狀態下connect不阻塞,直接返回-1,connect返回-1是對的
然後通過select進行判斷是否連線上
同步狀態下connect阻塞,系統莫認時間75秒後,返回成功或失敗
TCP程式設計的流程
伺服器端
// // main.cpp // Server // // Created by 藍貓 on 2018/12/13. // Copyright © 2018年 藍貓. All rights reserved. // #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #define PORT 25555 #define BACK_LOG 20 //佇列允許請求數 #define BUF_SIZE 256 // 緩衝區大小 #define IP "192.168.1.5" using std::cout; using std::endl; int main(int argc, const char * argv[]) { int ret; time_t tt; struct tm *ttm; char buf[BUF_SIZE]; pid_t pid;//定義程序描述符 int sockfd; // int clientfd; struct sockaddr_in host_addr; struct sockaddr_in client_addr; int length=sizeof(clientfd); sockfd=socket(AF_INET, SOCK_STREAM, 0); if(sockfd==-1) { cout<<"建立socket失敗"<<endl; exit(1); } bzero(&host_addr, sizeof(host_addr)); host_addr.sin_family=AF_INET;//TCP/IP協議 host_addr.sin_port=htons(PORT);//設定埠 host_addr.sin_addr.s_addr=INADDR_ANY;//本地ip ret=bind(sockfd, (const struct sockaddr *)&host_addr, sizeof(host_addr));//繫結ip和埠 if(ret==-1) { cout<<"bind失敗"<<endl; exit(1); } else { cout<<"bind成功"<<endl; } //監聽網路埠 ret=listen(sockfd, BACK_LOG); if(ret==-1) { cout<<"監聽失敗"<<endl; exit(1); } while (1) { /* 傾聽佇列之後 accept可以從傾聽套接字的完成佇列裡面接受一個連線,如果佇列是空,程序進入睡眠狀態。 accept呼叫成功 函式返回值是一個新的識別符號,標識接收的連線 第二個引數描述客戶機地址 第三個描述客戶機地址長度 */ //clientfd=accept(sockfd, (struct sockaddr *)&client_addr, &length);//接收連線請求 //clientfd=accept(sockfd, (struct sockaddr *)&client_addr,&length); clientfd = accept(sockfd, (struct sockaddr*)&client_addr, (socklen_t *)&length); if(clientfd==-1) { cout<<"接收失敗"<<endl; exit(1); } pid=fork(); if(pid==0) { while (1) { bzero(buf, sizeof(buf)); tt=time(NULL); ttm=localtime(&tt);//獲取當前時間引數 strcpy(buf, asctime(ttm));// 將時間拷貝到緩衝區 send(clientfd, buf, strlen(buf), 0);//傳送資料 sleep(2); } close(clientfd); } else if(pid>0) { close(clientfd);//父程序關閉套接字 ,準備下一個客戶端連線 } } return 0; }
客戶端
// // main.cpp // Client // // Created by 藍貓 on 2018/12/13. // Copyright © 2018年 藍貓. All rights reserved. // #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #define PORT 25555 #define BACK_LOG 20 //佇列允許請求數 #define BUF_SIZE 256 // 緩衝區大小 #define IP "192.168.1.5" using std::cout; using std::endl; int main(int argc, const char * argv[]) { int ret; char buf[BUF_SIZE]; int sockfd;//套接字描述符 struct sockaddr_in serv_addr;// 伺服器端的埠號和ip sockfd=socket(AF_INET, SOCK_STREAM, 0); if(sockfd==-1) { cout<<" socket建立失敗"<<endl; return 2; } bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(PORT); inet_aton(IP, (struct in_addr *)&serv_addr.sin_addr.s_addr); //serv_addr.sin_addr.s_addr=INADDR_ANY; cout<<"here1"<<endl; ret=connect(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr)); cout<<"here2"<<endl; if(ret==-1) { cout<<"connect失敗"<<endl; return 3; } else { cout<<"connect success"<<endl; } while (1) { bzero(buf, sizeof(buf)); recv(sockfd, buf, sizeof(buf), 0); printf("接收到資料:%s",buf); sleep(1); } close(sockfd); return 0; }
用多執行緒實現客戶端和伺服器端同時執行
//
// main.cpp
// 多執行緒實現tcp c/s互動
//
// Created by 藍貓 on 2018/12/14.
// Copyright © 2018年 藍貓. All rights reserved.
//
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#define PORT 25554
#define BACK_LOG 20 //佇列允許請求數
#define BUF_SIZE 256 // 緩衝區大小
#define IP "192.168.1.5"
using std::cout;
using std::endl;
int server()
{
int ret;
time_t tt;
struct tm *ttm;
char buf[BUF_SIZE];
pid_t pid;//定義程序描述符
int sockfd; //
int clientfd;
struct sockaddr_in host_addr;
struct sockaddr_in client_addr;
int length=sizeof(clientfd);
sockfd=socket(AF_INET, SOCK_STREAM, 0);
if(sockfd==-1)
{
cout<<"伺服器:建立socket失敗"<<endl;
exit(1);
}
bzero(&host_addr, sizeof(host_addr));
host_addr.sin_family=AF_INET;//TCP/IP協議
host_addr.sin_port=htons(PORT);//設定埠
host_addr.sin_addr.s_addr=INADDR_ANY;//本地ip
ret=bind(sockfd, (const struct sockaddr *)&host_addr, sizeof(host_addr));//繫結ip和埠
if(ret==-1)
{
cout<<"伺服器:bind失敗"<<endl;
exit(1);
}
else
{
cout<<"伺服器:bind成功"<<endl;
}
//監聽網路埠
cout<<"伺服器:開始監聽"<<endl;
ret=listen(sockfd, BACK_LOG);
if(ret==-1)
{
cout<<"伺服器:監聽失敗"<<endl;
exit(1);
}
while (1)
{
/*
傾聽佇列之後 accept可以從傾聽套接字的完成佇列裡面接受一個連線,如果佇列是空,程序進入睡眠狀態。
accept呼叫成功
函式返回值是一個新的識別符號,標識接收的連線
第二個引數描述客戶機地址 第三個描述客戶機地址長度
*/
//clientfd=accept(sockfd, (struct sockaddr *)&client_addr, &length);//接收連線請求
//clientfd=accept(sockfd, (struct sockaddr *)&client_addr,&length);
cout<<"伺服器:準備接收"<<endl;
clientfd = accept(sockfd, (struct sockaddr*)&client_addr, (socklen_t *)&length);
if(clientfd==-1)
{
cout<<"伺服器:接收失敗"<<endl;
exit(1);
}
pid=fork();
if(pid==0)
{
while (1)
{
bzero(buf, sizeof(buf));
tt=time(NULL);
ttm=localtime(&tt);//獲取當前時間引數
strcpy(buf, asctime(ttm));// 將時間拷貝到緩衝區
send(clientfd, buf, strlen(buf), 0);//傳送資料
sleep(2);
}
close(clientfd);
}
else if(pid>0)
{
close(clientfd);//父程序關閉套接字 ,準備下一個客戶端連線
}
}
return 0;
}
int client()
{
int ret;
char buf[BUF_SIZE];
int sockfd;//套接字描述符
struct sockaddr_in serv_addr;// 伺服器端的埠號和ip
sockfd=socket(AF_INET, SOCK_STREAM, 0);
if(sockfd==-1)
{
cout<<" 客戶端:socket建立失敗"<<endl;
return 2;
}
bzero(&serv_addr, sizeof(serv_addr));
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(PORT);
//inet_aton(IP, (struct in_addr *)&serv_addr.sin_addr.s_addr);
serv_addr.sin_addr.s_addr=INADDR_ANY;
cout<<"客戶端:準備connect"<<endl;
ret=connect(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
cout<<"客戶端:connect完成"<<endl;
if(ret==-1)
{
cout<<"客戶端:connect失敗"<<endl;
return 3;
}
else
{
cout<<"客戶端:connect success"<<endl;
}
while (1)
{
bzero(buf, sizeof(buf));
recv(sockfd, buf, sizeof(buf), 0);
printf("客戶端:接收到資料:%s",buf);
sleep(1);
}
close(sockfd);
return 0;
}
void *thread_server(void*arg)
{
server();
pthread_exit(NULL);
}
void *thread_client(void*arg)
{
client();
pthread_exit(NULL);
}
int main(int argc, const char * argv[])
{
cout<<"開始"<<endl;
pthread_t thread1,thread2;
int ret;
ret=pthread_create(&thread2, NULL, thread_client, NULL);
if(ret!=0)
{
printf("client建立失敗\n");
exit(1);
}
else
{
printf("client建立成功\n");
}
ret=pthread_create(&thread1, NULL, thread_server, NULL);
if(ret!=0)
{
printf("server建立失敗\n");
exit(1);
}
else
{
printf("server建立成功\n");
}
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}