日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client

發(fā)布時間:2024/9/27 编程问答 17 豆豆


1? Socket編程

socket這個詞可以表示很多概念:

TCP/IP協(xié)議中,“IP地址+TCPUDP端口號”唯一標識網(wǎng)絡(luò)通訊中的一個進程,“IP

地址+端口號”就稱為socket。

TCP協(xié)議中,建立連接的兩個進程各自有一個socket來標識,那么這兩個socket組成的socket pair就唯一標識一個連接。socket本身有“插座”的意思,因此用來描述網(wǎng)絡(luò)連

接的一對一關(guān)系。

TCP/IP協(xié)議最早在BSD UNIX上實現(xiàn),為TCP/IP協(xié)議設(shè)計的應(yīng)用層編程接口稱為socket

API

本章的主要內(nèi)容是socketAPI,主要介紹TCP協(xié)議的函數(shù)接口,最后介紹UDP協(xié)議和UNIX Domain Socket的函數(shù)接口。

11.1socketAPI

2 網(wǎng)絡(luò)字節(jié)序

我們已經(jīng)知道,內(nèi)存中的多字節(jié)數(shù)據(jù)相對于內(nèi)存地址有大端和小端之分,磁盤文件中的

多字節(jié)數(shù)據(jù)相對于文件中的偏移地址也有大端小端之分。網(wǎng)絡(luò)數(shù)據(jù)流同樣有大端小端之分,

那么如何定義網(wǎng)絡(luò)數(shù)據(jù)流的地址呢?發(fā)送主機通常將發(fā)送緩沖區(qū)中的數(shù)據(jù)按內(nèi)存地址從低到高的順序發(fā)出,接收主機把從網(wǎng)絡(luò)上接到的字節(jié)依次保存在接收緩沖區(qū)中,也是按內(nèi)存地址從低到高的順序保存,因此,網(wǎng)絡(luò)數(shù)據(jù)流的地址應(yīng)這樣規(guī)定:先發(fā)出的數(shù)據(jù)是低地址,后發(fā)出的數(shù)據(jù)是高地址。

??? TCP/IP協(xié)議規(guī)定,網(wǎng)絡(luò)數(shù)據(jù)流應(yīng)采用大端字節(jié)序,即低地址高字節(jié)。例如上一節(jié)的UDP

段格式,地址0-116位的源端口號,如果這個端口號是10000x3e8),則地址00x03

地址10xe8,也就是先發(fā)0x03,再發(fā)0xe8,這16位在發(fā)送主機的緩沖區(qū)中也應(yīng)該是低地址存0x03,高地址存0xe8。但是,如果發(fā)送主機是小端字節(jié)序的,這16位被解釋成0xe803,而不是1000。因此,發(fā)送主機把1000填到發(fā)送緩沖區(qū)之前需要做字節(jié)序的轉(zhuǎn)換。同樣地,接收主機如果是小端字節(jié)序的,接到16位的源端口號也要做字節(jié)序的轉(zhuǎn)換。如果主機是大端字節(jié)序的,發(fā)送和接收都不需要做轉(zhuǎn)換。同理,32位的IP地址也要考慮網(wǎng)絡(luò)字節(jié)序和主機字節(jié)序的問題。

?

為使網(wǎng)絡(luò)程序具有可移植性,使同樣的C代碼在大端和小端計算機上編譯后都能正常運行,可以調(diào)用以下庫函數(shù)做網(wǎng)絡(luò)字節(jié)序和主機字節(jié)序的轉(zhuǎn)換。

3 函數(shù)介紹

A 依賴的頭文件

#include <arpa/inet.h>

B 函數(shù)聲明

#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

h表示hostn表示networkl表示32位長整數(shù),s表示16位短整數(shù)。

如果主機是小端字節(jié)序,這些函數(shù)將參數(shù)做相應(yīng)的大小端轉(zhuǎn)換然后返回,如果主機是大端字節(jié)序,這些函數(shù)不做轉(zhuǎn)換,將參數(shù)原封不動地返回。

?

uint32_t htonl(uint32_t hostlong);

名稱:

htonl

功能:

The htonl() function converts the unsigned integer hostlong? from? host byte order to network byte order

頭文件:

#include <arpa/inet.h>

函數(shù)原形:

uint32_t htonl(uint32_t hostlong);

參數(shù):

?

返回值:

?

?

uint16_t htons(uint16_t hostshort);

名稱:

htons

功能:

The htons() function converts the unsigned short integer hostshort from

host byte order to network byte order.

頭文件:

#include <arpa/inet.h>

函數(shù)原形:

uint16_t htons(uint16_t hostshort);

參數(shù):

?

返回值:

?

?

uint32_t ntohl(uint32_t netlong);

名稱:

ntohl

功能:

The ntohl() function converts the unsigned integer netlong from network

byte order to host byte order.

頭文件:

#include <arpa/inet.h>

函數(shù)原形:

uint32_t ntohl(uint32_t netlong);

參數(shù):

?

返回值:

?

?

uint16_t ntohs(uint16_t netshort);

名稱:

ntohs

功能:

The ntohs() function converts the unsigned short integer netshort from

network byte order to host byte order.

頭文件:

#include <arpa/inet.h>

函數(shù)原形:

uint16_t ntohs(uint16_t netshort);

參數(shù):

?

返回值:

?

?

4 IP地址轉(zhuǎn)換函數(shù)

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

int inet_aton(const char *cp, structin_addr *inp);

in_addr_t inet_addr(const char *cp);

char *inet_ntoa(struct in_addr in);

只能處理IPv4ip地址

不可重入函數(shù)

注意參數(shù)是struct in_addr

?

現(xiàn)在

#include <arpa/inet.h>

int inet_pton(int af, const char *src, void*dst);

const char *inet_ntop(int af, const void*src, char *dst, socklen_t size);

支持IPv4IPv6

可重入函數(shù)

?

其中inet_ptoninet_ntop不僅可以轉(zhuǎn)換IPv4in_addr,還可以轉(zhuǎn)換IPv6in6_addr,因此函數(shù)接口是void*addrptr

?

5 sockaddr數(shù)據(jù)結(jié)構(gòu)

??? strcutsockaddr 很多網(wǎng)絡(luò)編程函數(shù)誕生早于IPv4協(xié)議,那時候都使用的是sockaddr結(jié)

構(gòu)體,為了向前兼容,現(xiàn)在sockaddr退化成了(void *)的作用,傳遞一個地址給函數(shù),至

于這個函數(shù)是sockaddr_in還是sockaddr_in6,由地址族確定,然后函數(shù)內(nèi)部再強制類型轉(zhuǎn)

化為所需的地址類型

11.2sockaddr數(shù)據(jù)結(jié)構(gòu)

struct sockaddr {

sa_family_t sa_family; /* address family, AF_xxx */

char sa_data[14]; /* 14 bytes of protocol address */

};

?

struct sockaddr_in {

__kernel_sa_family_t sin_family; /* Address family */

__be16 sin_port; /* Port number */

struct in_addr sin_addr; /* Internet address */

/* Pad to size of `struct sockaddr'. */

unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -

sizeof(unsigned short int) - sizeof(struct in_addr)];

};

?

/* Internet address. */

struct in_addr {

__be32 s_addr;

};

?

struct sockaddr_in6 {

unsigned short int sin6_family; /* AF_INET6*/

__be16 sin6_port; /* Transport layer port # */

__be32 sin6_flowinfo; /* IPv6 flow information */

struct in6_addr sin6_addr; /* IPv6 address */

__u32 sin6_scope_id; /* scope id (new in RFC2553) */

};

?

struct in6_addr {

union {

__u8 u6_addr8[16];

__be16 u6_addr16[8];

__be32 u6_addr32[4];

} in6_u;

#define s6_addr in6_u.u6_addr8

#define s6_addr16 in6_u.u6_addr16

#define s6_addr32 in6_u.u6_addr32

};

?

#define UNIX_PATH_MAX 108

struct sockaddr_un {

__kernel_sa_family_t sun_family; /* AF_UNIX */

char sun_path[UNIX_PATH_MAX]; /* pathname */

};

?

Pv4IPv6的地址格式定義在netinet/in.h中,IPv4地址用sockaddr_in結(jié)構(gòu)體表示,包

16位端口號和32IP地址,IPv6地址用sockaddr_in6結(jié)構(gòu)體表示,包括16位端口號、128IP地址和一些控制字段。UNIX Domain Socket的地址格式定義在sys/un.h中,用sockaddr_un結(jié)構(gòu)體表示。各種socket地址結(jié)構(gòu)體的開頭都是相同的,前16位表示整個結(jié)構(gòu)體的長度(并不是所有UNIX的實現(xiàn)都有長度字段,如Linux就沒有),后16位表示地址類型。IPv4IPv6Unix Domain Socket的地址類型分別定義為常數(shù)AF_INET、AF_INET6AF_UNIX。這樣,只要取得某種sockaddr結(jié)構(gòu)體的首地址,不需要知道具體是哪種類型的sockaddr結(jié)構(gòu)體,就可以根據(jù)地址類型字段確定結(jié)構(gòu)體中的內(nèi)容。因此,socket API可以接受各種類型的sockaddr結(jié)構(gòu)體指針做參數(shù),例如bind、accept、connect等函數(shù),這些函數(shù)的參數(shù)應(yīng)該設(shè)計成void *類型以便接受各種類型的指針,但是sock API的實現(xiàn)早于ANSI C標準化,那時還沒有void *類型,因此這些函數(shù)的參數(shù)都用struct sockaddr *類型表示,在傳遞參數(shù)之前要強制類型轉(zhuǎn)換一下,例如:

struct sockaddr_in servaddr;

/* initialize servaddr */

bind(listen_fd,(struct sockaddr*)&servaddr,sizeof(servaddr));

?

6 網(wǎng)絡(luò)套接字函數(shù)

A socket

#include <sys/types.h>

#include <sys/socket.h>

?

int socket(int domain,int types,intprotocol);

?

domain:

AF_INET 這是大多數(shù)用來產(chǎn)生socket的協(xié)議,使用TCPUDP來傳輸,用IPv4的地址

AF_INET6 與上面類似,不過是來用IPv6的地址

AF_UNIX 本地協(xié)議,使用在UnixLinux系統(tǒng)上,一般都是當(dāng)客戶端和服務(wù)器在同一臺及其上的時候使用

?

type:

SOCK_STREAM 這個協(xié)議是按照順序的、可靠的、數(shù)據(jù)完整的基于字節(jié)流的連接。這是一個使用最多的socket類型,這個socket是使用TCP來進行傳輸。

SOCK_DGRAM 這個協(xié)議是無連接的、固定長度的傳輸調(diào)用。該協(xié)議是不可靠的,使用UDP來進行它的連接。

SOCK_SEQPACKET 這個協(xié)議是雙線路的、可靠的連接,發(fā)送固定長度的數(shù)據(jù)包進行傳輸。必須把這個包完整的接受才能進行讀取。

SOCK_RAW 這個socket類型提供單一的網(wǎng)絡(luò)訪問,這個socket類型使用ICMP公共協(xié)議。(ping、traceroute使用該協(xié)議)

SOCK_RDM 這個類型是很少使用的,在大部分的操作系統(tǒng)上沒有實現(xiàn),它是提供給數(shù)據(jù)鏈路層使用,不保證數(shù)據(jù)包的順序

?

protocol:

0 默認協(xié)議

返回值:

成功返回一個新的文件描述符,失敗返回-1,設(shè)置errno

?

socket()打開一個網(wǎng)絡(luò)通訊端口,如果成功的話,就像open()一樣返回一個文件描述符,應(yīng)用程序可以像讀寫文件一樣用read/write在網(wǎng)絡(luò)上收發(fā)數(shù)據(jù),如果socket()調(diào)用出錯則返回-1。對于IPv4domain參數(shù)指定為AF_INET。對于TCP協(xié)議,type參數(shù)指定為SOCK_STREAM,表示面向流的傳輸協(xié)議。如果是UDP協(xié)議,則type參數(shù)指定為SOCK_DGRAM,表示面向數(shù)據(jù)報的傳輸協(xié)議。protocol參數(shù)的介紹從略,指定為0即可。

?

7 bind

A 依賴的頭文件

#include <sys/types.h> /* See NOTES*/

#include <sys/socket.h>

B 函數(shù)聲明

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

sockfd:

???socket文件描述符

addr:

構(gòu)造出IP地址加端口號

addrlen:

???sizeof(addr)長度

返回值:

??? 成功返回0,失敗返回-1,設(shè)置errno

?

服務(wù)器程序所監(jiān)聽的網(wǎng)絡(luò)地址和端口號通常是固定不變的,客戶端程序得知服務(wù)器程序

的地址和端口號后就可以向服務(wù)器發(fā)起連接,因此服務(wù)器需要調(diào)用bind綁定一個固定的網(wǎng)絡(luò)地址和端口號。

??? bind()的作用是將參數(shù)sockfdaddr綁定在一起,使sockfd這個用于網(wǎng)絡(luò)通訊的文件

描述符監(jiān)聽addr所描述的地址和端口號。前面講過,struct sockaddr *是一個通用指針類

型,addr參數(shù)實際上可以接受多種協(xié)議的sockaddr結(jié)構(gòu)體,而它們的長度各不相同,所以需要第三個參數(shù)addrlen指定結(jié)構(gòu)體的長度。如:

?

struct sockaddr_in servaddr;

bzero(&servaddr, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr =htonl(INADDR_ANY);

servaddr.sin_port = htons(8000);

首先將整個結(jié)構(gòu)體清零,然后設(shè)置地址類型為AF_INET,網(wǎng)絡(luò)地址為INADDR_ANY,這個宏表示本地的任意IP地址,因為服務(wù)器可能有多個網(wǎng)卡,每個網(wǎng)卡也可能綁定多個IP地址,這樣設(shè)置可以在所有的IP地址上監(jiān)聽,直到與某個客戶端建立了連接時才確定下來到底用哪個IP地址,端口號為8000。

?

8 listen

#include <sys/types.h> /* See NOTES*/

#include <sys/socket.h>

?

int listen(int sockfd, int backlog);

sockfd:

socket文件描述符

backlog:

排隊建立3次握手隊列和剛剛建立3次握手隊列的鏈接數(shù)和

?

查看系統(tǒng)默認backlog

cat /proc/sys/net/ipv4/tcp_max_syn_backlog

典型的服務(wù)器程序可以同時服務(wù)于多個客戶端,當(dāng)有客戶端發(fā)起連接時,服務(wù)器調(diào)用的

accept()返回并接受這個連接,如果有大量的客戶端發(fā)起連接而服務(wù)器來不及處理,尚未

accept的客戶端就處于連接等待狀態(tài),listen()聲明sockfd處于監(jiān)聽狀態(tài),并且最多允許有

backlog個客戶端處于連接待狀態(tài),如果接收到更多的連接請求就忽略。listen()成功返回

0,失敗返回-1。

?

9 ?accept

#include <sys/types.h> /* See NOTES*/

#include <sys/socket.h>

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

sockdf:

socket文件描述符

addr:

傳出參數(shù),返回鏈接客戶端地址信息,含IP地址和端口號

addrlen:

傳入傳出參數(shù)(值-結(jié)果),傳入sizeof(addr)大小,函數(shù)返回時返回真正接收到地址結(jié)構(gòu)體的大小

返回值:

成功返回一個新的socket文件描述符,用于和客戶端通信,失敗返回-1,設(shè)置errno

?

三方握手完成后,服務(wù)器調(diào)用accept()接受連接,如果服務(wù)器調(diào)用accept()時還沒有

客戶端的連接請求,就阻塞等待直到有客戶端連接上來。addr是一個傳出參數(shù),accept()

返回時傳出客戶端的地址和端口號。addrlen參數(shù)是一個傳入傳出參數(shù)(value-result argument),傳入的是調(diào)用者提供的緩沖區(qū)addr的長度以避免緩沖區(qū)溢出問題,傳出的是客

戶端地址結(jié)構(gòu)體的實際長度(有可能沒有占滿調(diào)用者提供的緩沖區(qū))。如果給addr參數(shù)傳

NULL,表示不關(guān)心客戶端的地址。

?

我們的服務(wù)器程序結(jié)構(gòu)是這樣的:

while (1) {

cliaddr_len = sizeof(cliaddr);

connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&cliaddr_len);

n = read(connfd, buf, MAXLINE);

......

close(connfd);

}

?

整個是一個while死循環(huán),每次循環(huán)處理一個客戶端連接。由于cliaddr_len是傳入傳出

參數(shù),每次調(diào)用accept()之前應(yīng)該重新賦初值。accept()的參數(shù)listenfd是先前的監(jiān)聽文件

描述符,而accept()的返回值是另外一個文件描述符connfd,之后與客戶端之間就通過這個

connfd通訊,最后關(guān)閉connfd斷開連接,而不關(guān)閉listenfd,再次回到循環(huán)開頭listenfd

然用作accept的參數(shù)。accept()成功返回一個文件描述符,出錯返回-1。

?

10 connect

#include <sys/types.h> /* See NOTES*/

#include <sys/socket.h>

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

sockdf:

socket文件描述符

addr:

傳入?yún)?shù),指定服務(wù)器端地址信息,含IP地址和端口號

addrlen:

傳入?yún)?shù),傳入sizeof(addr)大小

返回值:

成功返回0,失敗返回-1,設(shè)置errno

?

客戶端需要調(diào)用connect()連接服務(wù)器,connectbind的參數(shù)形式一致,區(qū)別在于bind的參數(shù)是自己的地址,而connect的參數(shù)是對方的地址。connect()成功返回0,出錯返回-1。

?

11 C/S模型-TCP

??? 下圖是基于TCP協(xié)議的客戶端/服務(wù)器程序的一般流程:

11.3: TCP協(xié)議通訊流程

服務(wù)器調(diào)用socket()、bind()、listen()完成初始化后,調(diào)用accept()阻塞等待,處于

監(jiān)聽端口的狀態(tài),客戶端調(diào)用socket()初始化后,調(diào)用connect()發(fā)出SYN段并阻塞等待服

務(wù)器應(yīng)答,服務(wù)器應(yīng)答一個SYN-ACK段,客戶端收到后從connect()返回,同時應(yīng)答一個ACK

段,服務(wù)器收到后從accept()返回。

數(shù)據(jù)傳輸?shù)倪^程:

建立連接后,TCP協(xié)議提供全雙工的通信服務(wù),但是一般的客戶端/服務(wù)器程序的流程是由客戶端主動發(fā)起請求,服務(wù)器被動處理請求,一問一答的方式。因此,服務(wù)器從accept()

返回后立刻調(diào)用read(),讀socket就像讀管道一樣,如果沒有數(shù)據(jù)到達就阻塞等待,這時客

戶端調(diào)用write()發(fā)送請求給服務(wù)器,服務(wù)器收到后從read()返回,對客戶端的請求進行處

理,在此期間客戶端調(diào)用read()阻塞等待服務(wù)器的應(yīng)答,服務(wù)器調(diào)用write()將處理結(jié)果發(fā)

回給客戶端,再次調(diào)用read()阻塞等待下一條請求,客戶端收到后從read()返回,發(fā)送下一

條請求,如此循環(huán)下去。

如果客戶端沒有更多的請求了,就調(diào)用close()關(guān)閉連接,就像寫端關(guān)閉的管道一樣,

服務(wù)器的read()返回0,這樣服務(wù)器就知道客戶端關(guān)閉了連接,也調(diào)用close()關(guān)閉連接。注

意,任何一方調(diào)用close()后,連接的兩個傳輸方向都關(guān)閉,不能再發(fā)送數(shù)據(jù)了。如果一方

調(diào)用shutdown()則連接處于半關(guān)閉狀態(tài),仍可接收對方發(fā)來的數(shù)據(jù)。

在學(xué)習(xí)socket API時要注意應(yīng)用程序和TCP協(xié)議層是如何交互的: *應(yīng)用程序調(diào)用某個

socket函數(shù)時TCP協(xié)議層完成什么動作,比如調(diào)用connect()會發(fā)出SYN*應(yīng)用程序如何知

TCP協(xié)議層的狀態(tài)變化,比如從某個阻塞的socket函數(shù)返回就表明TCP協(xié)議收到了某些段,再比如read()返回0就表明收到了FIN

12 TCP服務(wù)器客戶端案例說明

server.c

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <string.h>

#include <netinet/in.h>

#include <ctype.h>

#include <unistd.h>

?

#define SERVER_PORT 8000

#define MAXLINE 4096

?

int main(void)

{

??? struct sockaddr_in serveraddr,clientaddr;

??? int sockfd,addrlen,confd,len,i;

??? //存儲ip地址

??? char ipstr[128];

??? char buf[MAXLINE];

???

??? //1.socket

??? //AF_INET:表示使用的是Ipv4協(xié)議,如果想使用ipv6,使用AF_INET6

??? //SOCK_STREAM:表示使用的是TCP協(xié)議

??? sockfd = socket(AF_INET,SOCK_STREAM,0);

??? //2.bind,bzero將內(nèi)容清零

??? bzero(&serveraddr,sizeof(serveraddr));

??? /* 地址族協(xié)議IPv4 */

??? serveraddr.sin_family = AF_INET;

??? /* IP地址 */

??? serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);

??? /*端口號*/

??? serveraddr.sin_port = htons(SERVER_PORT);

??? bind(sockfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));

??? //3.listen,表示最大等待排隊的數(shù)量為128

??? listen(sockfd,128);

??? while(1) {

??????? //4.accept 阻塞監(jiān)聽客戶端鏈接請求

??????? addrlen = sizeof(clientaddr);

??????? confd = accept(sockfd,(struct sockaddr *)&clientaddr,&addrlen);

??????? //輸出客戶端IP地址和端口號

??????? inet_ntop(AF_INET,&clientaddr.sin_addr.s_addr,ipstr,sizeof(ipstr));

??????? //打印除ip地址和端口號

??????? printf("client ip %s\tport %d\n",

??????????? inet_ntop(AF_INET,&clientaddr.sin_addr.s_addr,ipstr,sizeof(ipstr)),

??????????? ntohs(clientaddr.sin_port));

?

??????? //和客戶端交互數(shù)據(jù)操作confd

??????? //5.處理客戶端請求,read,write默認是阻塞的。

??????? len = read(confd,buf,sizeof(buf));

??????? i = 0;

??????? while(i < len) {

??????????? buf[i] = toupper(buf[i]);

?????? ?????i++;

??????? }

??????? write(confd,buf,len);

??????? //發(fā)生里4次鏈接

??????? close(confd);

??? }

??? close(sockfd);

?

??? return 0;

}

client.c

#include <netinet/in.h>

#include <stdio.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <arpa/inet.h>

#include <string.h>

#include <stdlib.h>

#include <sys/stat.h>

#include <unistd.h>

#include <fcntl.h>

?

#define SERVER_PORT 8000

#define MAXLINE 4096

?

int main(int argc,char *argv[])

{

??? struct sockaddr_in serveraddr;

??? int confd,len;

??? char ipstr[] = "192.168.6.14";

??? char buf[MAXLINE];

??? if(argc < 2) {

??????? printf("./client str\n");

??????? exit(1);

??? }

??? //1、創(chuàng)建一個socket

??? confd = socket(AF_INET,SOCK_STREAM,0);

??? //2、初始化服務(wù)器地址

??? bzero(&serveraddr,sizeof(serveraddr));

??? serveraddr.sin_family = AF_INET;

??? //"192.168.6.14"

??? inet_pton(AF_INET,ipstr,&serveraddr.sin_addr.s_addr);

??? serveraddr.sin_port = htons(SERVER_PORT);

??? //3.鏈接服務(wù)器處理數(shù)據(jù)

??? connect(confd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));

??? //4.請求服務(wù)器處理數(shù)據(jù)

??? write(confd,argv[1],strlen(argv[1]));

??? len = read(confd,buf,sizeof(buf));

??? write(STDOUT_FILENO,buf,len);

?

??? //關(guān)閉socket

??? close(confd);

??? return 0;

}

Makefile

all:server client

?

server:server.c

???????? gcc $< -o $@

client:client.c

???????? gcc $< -o $@

?

.PHONY:clean

clean:

???????? rm -f server

???????? rm -f client

運行:

在終端上輸入make,先啟動server端,在啟動client,在啟動客戶端的時候同時輸入字符串。

客戶端運行效果:

總結(jié)

以上是生活随笔為你收集整理的1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 巨大黑人极品videos精品 | 春色av| 中文字幕国产一区 | 中文字幕久久精品 | 日本精品在线观看视频 | 麻豆亚洲 | 一区二区精品视频在线观看 | www.夜夜| 亚洲精品成人电影 | 黄色av小说在线观看 | 91原视频 | 欧美18一19性内谢 | 青青草手机在线视频 | 女教师痴汉调教hd中字 | 人人天天夜夜 | 少妇15p | 亚洲国产aaa | 七仙女欲春2一级裸体片 | 深田咏美在线x99av | 肉丝美脚视频一区二区 | 高跟鞋肉丝交足91 | 男生操女生屁股 | 免费高清成人 | 国产喷水视频 | 中日韩午夜理伦电影免费 | 亚洲区综合 | 麻豆久久久| 久久久久国产精品夜夜夜夜夜 | 日韩在线免费播放 | 99re热这里只有精品视频 | 少妇av片 | 国产精品福利在线播放 | 日本美女动态 | 国产伦理久久精品久久久久 | 邻居少妇张开双腿让我爽一夜 | 中文字幕5566 | 久久久久99精品成人片三人毛片 | 一区二区在线视频免费观看 | 一级片大全 | 综合色88| 青青视频免费在线观看 | 97视频在线观看免费高清完整版在线观看 | 影音先锋在线播放 | 美女脱了裤子让男人捅 | 中文字幕超清在线观看 | 亚洲成人av中文字幕 | 无罩大乳的熟妇正在播放 | 成人久久久久 | 国产精品欧美亚洲 | 色多多av | 亚洲乱人伦 | 一个人看的视频www 色就是色网站 | 国产伦精品一区二区三区视频黑人 | 亚洲精品国产精品国自产观看浪潮 | 精品一区二区不卡 | 国产色吧 | 婷婷6月天 | 久久国产网 | 欧美肥妇bwbwbwbxx | 小sao货水好多真紧h无码视频 | 亚洲精品无码久久久久久久 | 激情偷乱人成视频在线观看 | 无码少妇精品一区二区免费动态 | 日本美女动态 | 国产亚洲精品久久久久久无几年桃 | 国产又粗又猛又爽又黄91精品 | av一区二区三 | 国产乱码一区二区三区 | 欧美黄色一级片视频 | 亚洲 欧美 日韩 国产综合 在线 | 男人的天堂av网站 | 韩国久久久久久 | 欧美成人精品 | 欧美日韩性生活视频 | 成年人拍拍视频 | 深夜毛片| 午夜精品久久久久久久久 | 欧美韩日国产 | 久久国产精品久久 | wwwxxx国产| 国产区一区二 | 国产精品久久av无码一区二区 | 男人天堂成人 | 成人久久久精品乱码一区二区三区 | 最新福利在线 | 总裁边开会边做小娇妻h | 国产成人av在线播放 | 久久精品在线播放 | 日韩欧美在线一区 | 伊人色影院 | 木下凛凛子av一区二区三区 | 久久久无码精品亚洲国产 | 91在线视频免费看 | 日韩一区二区三区视频在线观看 | 亚州视频在线 | 中文字幕日韩在线播放 | 色婷婷一区二区三区 | 精品无码久久久久成人漫画 | 这里只有精品66 |