使用套接字實現簡單TCP伺服器客戶端模型

2021-08-03 08:51:31 字數 3845 閱讀 1128

利用套接字實現乙個簡單的tcp伺服器客戶端模型基本步驟如下:

1.建立套接字

#include

#include

int socket(int domain, int type, int protocol);

引數描述:

domian:協議域,af_inet 對應 ipv4,af_inet6  對應  ipv6, af_unix 表示這個socket是非網路形式的unix域,可以用來進行非網路形式的程序間通訊。

type:指定socket型別

1.sock_stream 這個協議是按照順序的、可靠的、資料完整的基於位元組流的連線。  這是乙個使用最多的socket型別,這個socket是使用tcp來進行傳輸。

2.sock_dgram 這個協議是無連線的、固定長度的傳輸呼叫。該協議是不可靠的,使用udp來進行它的連線。

3.sock_raw 這個socket型別提供單一的網路訪問,這個socket型別使用icmp公共協議。(ping、traceroute使用該協議)

返回值:

成功返回socket描述符,失敗返回-1

2.將伺服器ip與埠和套接字進行繫結

#include

#include

int bind(int sockfd, const struct sockaddr *addr,  socklen_t addrlen);

引數描述:

sockfd:通過socket()函式建立,用來表示唯一乙個socket

返回值:

成功返回0,失敗返回-1

注意:

struct sockaddr_in

;struct in_addr;

3.監聽請求

#include

#include

int listen(int sockfd, int backlog);

引數描述:

sockfd:要監聽的套接字

backlog:連線佇列長度

backlog 具體一些是什麼意思呢?每乙個連入請求都要進入乙個連入請求佇列,等待listen 的程式呼叫accept()函式來接受這個連線。當系統還沒有呼叫accept()函式的時候,如果有很多連線,那麼本地能夠等待的最大數目就是backlog 的數值。

返回值:

成功返回0,失敗返回-1

4.伺服器端接受監聽到的請求

當伺服器端進行監聽到乙個連線請求時,就可以使用accept()函式來接受這個請求。

#include

#include

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

引數描述:

socket:伺服器的套接字

addrlen:位址長度(sizeof(addr))

返回值:

成功返回乙個新的套接字描述符,代表與返回客戶端的tcp連線

5.客戶端連線伺服器

#include

#include

int connect(int sockfd, const struct sockaddr *addr,  socklen_t addrlen);

引數描述:

sockfd:客戶端的sockfd

addrlen:位址長度(sizeof(addr))

返回值:

成功返回0,失敗返回-1

注意:

在實現過程中還應注意網路位元組序的問題,主機的位元組序是不確定的,有的使用大端儲存,有的使用小端儲存,為了不使網路通訊因為機器之間儲存模式而造成錯誤,tcp/ip協議規定網路資料流使用大端位元組序。

下面庫函式可以完成主機序列和為網路序列的轉換:

#include

//主機序列到網路序列

uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

//網路序列到主機序列

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

server:

#include#include#include#include#include#include#includestatic void usage(char* proc)

int startup(char* ip, int port)

printf("sock = %d\n", sock);

struct sockaddr_in local;

//確定位址協議型別

local.sin_family = af_inet;

//繫結埠

local.sin_port = htons(port);

//繫結ip

//這裡的ip是點分十進位制,使用inet_addr()可以將其轉換成二進位制

local.sin_addr.s_addr = inet_addr(ip);

//2.繫結網路特性將套接字與伺服器ip和埠號繫結

if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)

//3.監聽請求

if(listen(sock, 10) < 0)

return sock;

}int main(int argc, char* argv)

//獲取套接字

int listen_sock = startup(argv[1], atoi(argv[2]));

while(1)

while(1)

else if(s == 0)

else}}

return 0;

}

client:

#include#include#include#include#include#includestatic void usage(char *proc)

int main(int argc, char* argv)

//建立套接字

int sock = socket(af_inet, sock_stream,0);

if(sock < 0)

struct sockaddr_in server;

server.sin_family = af_inet;

server.sin_port = htons(atoi(argv[2]));

server.sin_addr.s_addr = inet_addr(argv[1]);

//將建立的套接字,連入指定的網路服務中,這裡連到了伺服器

if(connect(sock,(struct sockaddr*)&server, sizeof(server)) < 0)

char buf[1024];

while(1)

if(s < 0)}}

return 0;

}

c 實現tcp伺服器 TCP套接字 C實現

udp套接字的介紹見另一篇文章 這篇文章已經介紹了很多基礎的巢狀字的函式,在這裡不做贅述,這篇實驗報告,只介紹udp中沒有的函式 實際上套接字是網際網路應用程式的介面,可以把它理解為你辦公室的門 當你想從你的辦公室給同事傳遞訊息時,你住需要把信放在門口,然後會有人 傳輸層等 會把信放到你的同事的門口...

套接字實現Udp伺服器

udp伺服器的實現與tcp之間是很有差別的,下面我們來說要注意的幾點 首先 需要呼叫socket建立套接字 socket函式的引數與tcp呼叫時有點不一樣,udp是資料報傳輸,所以傳輸的型別是要改為sock dgram,也就是socket函式的第二個引數需要更改 呼叫bind來繫結伺服器,所以我們需...

基於TCP套接字實現的簡單Demo

由於 的注釋已經很詳盡了,所以這裡不再作過多說明.僅僅貼出 和結果圖.值得注意的是必須先啟動server程式再啟動client.server include 套接字型檔 include define port 6000 伺服器端口 define msgsize 1024 收發緩衝區的大小 pragm...