流程:
服務(wù)器端先初始化Socket,然后與端口綁定(bind),對端口進(jìn)行監(jiān)聽(listen),調(diào)用accept阻塞,等待客戶端連接。
在這時(shí)如果有個(gè)客戶端初始化一個(gè)Socket,然后連接服務(wù)器(connect),如果連接成功,這時(shí)客戶端與服務(wù)器端的連接就建立了。客戶端發(fā)送數(shù)據(jù)請求,服務(wù)器端接收請求并處理請求,然后把回應(yīng)數(shù)據(jù)發(fā)送給客戶端,客戶端讀取數(shù)據(jù),最后關(guān)閉連接,一次交互結(jié)束。

Socket編程實(shí)例
服務(wù)器端:一直監(jiān)聽本機(jī)的8000號端口,如果收到連接請求,將接收請求并接收客戶端發(fā)來的消息,并向客戶端返回消息。
/* File Name: server.c */?
?#include
#include
#include
#include
#include
#include
#include
#define DEFAULT_PORT 8000?
#define MAXLINE 4096?
int main(int argc, char** argv)?
{?
????????int? ? socket_fd, connect_fd;?
????????struct sockaddr_in? ? servaddr;?
????????char? ? buff[4096];?
????????int? ? n;?
????????//初始化Socket?
????????if( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {?
????????????????printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);?
????????????????exit(0);?
????????}?
????????//初始化?
????????memset(&servaddr, 0, sizeof(servaddr));?
????????servaddr.sin_family = AF_INET;?
????????servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址設(shè)置成INADDR_ANY,讓系統(tǒng)自動(dòng)獲取本機(jī)的IP地址。?
????????servaddr.sin_port = htons(DEFAULT_PORT);//設(shè)置的端口為DEFAULT_PORT?
????????//將本地地址綁定到所創(chuàng)建的套接字上?
????????if( bind(socket_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {?
????????????????printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);?
????????????????exit(0);?
? ? ? ? }?
? ??????//開始監(jiān)聽是否有客戶端連接?
????????if( listen(socket_fd, 10) == -1) {?
????????????????printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);?
????????????????exit(0);?
????????}?
????????printf("======waiting for client's request======\n");?
????????while(1) {?
? ??????????????//阻塞直到有客戶端連接,不然多浪費(fèi)CPU資源。?
????????????????if( (connect_fd = accept(socket_fd, (struct sockaddr*)NULL, NULL)) == -1) {?
????????????????????????printf("accept socket error: %s(errno: %d)",strerror(errno),errno);?
????????????????????????continue;?
????????????????}?
????????????????//接受客戶端傳過來的數(shù)據(jù)?
????????????????n = recv(connect_fd, buff, MAXLINE, 0);?
????????????????//向客戶端發(fā)送回應(yīng)數(shù)據(jù)?
????????????????if(!fork()) {? /*紫禁城*/?
????????????????????????if(send(connect_fd, "Hello,you are connected!\n", 26,0) == -1)? {
????????????????????????????????perror("send error");?
? ? ? ? ? ? ? ? ? ? ? ? }
????????????????????????close(connect_fd);?
????????????????????????exit(0);?
????????????????}?
????????????????buff[n] = '\0';?
????????????????printf("recv msg from client: %s\n", buff);?
????????????????close(connect_fd);?
????????}?
????????close(socket_fd);?
}?
客戶端:/* File Name: client.c */
?#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 4096
?int main(int argc, char** argv)? ?{?
?????????int sockfd, n,rec_len;
????????char recvline[4096], sendline[4096];?
?????????char buf[MAXLINE];?
?????????struct sockaddr_in servaddr;?
?????????if( argc != 2)? {
?????????????printf("usage: ./client\n");
? ? ? ? ? ? ?exit(0);?
????????}?
????????if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {?
????????????????printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);?
????????????????exit(0);?
????????}?
????????memset(&servaddr, 0, sizeof(servaddr));?
????????servaddr.sin_family = AF_INET;?
????????servaddr.sin_port = htons(8000);?
????????if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {?
????????????????printf("inet_pton error for %s\n",argv[1]);?
????????????????exit(0);?
????????}?
????????if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0 ) {?
????????????????printf("connect error: %s(errno: %d)\n",strerror(errno),errno);?
????????????????exit(0);?
????????}?
????????printf("send msg to server: \n");?
????????fgets(sendline, 4096, stdin);?
????????if( send(sockfd, sendline, strlen(sendline), 0) < 0)?
????????{?
????????????????printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);?
????????????????exit(0);?
????????}?
????????if((rec_len = recv(sockfd, buf, MAXLINE,0)) == -1)? {?
????????????????perror("recv error");?
????????????????exit(1);?
????????}?
????????buf[rec_len]? = '\0';?
????????printf("Received : %s ",buf);?
????????close(sockfd);?
????????exit(0);?
}?
inet_pton 函數(shù)
inet_pton 是Linux下IP地址轉(zhuǎn)換函數(shù),可以在將IP地址在“點(diǎn)分十進(jìn)制”和“整數(shù)”之間轉(zhuǎn)換 ,是inet_addr的擴(kuò)展。
int inet_pton(int af, const char *src, void *dst);//轉(zhuǎn)換字符串到網(wǎng)絡(luò)地址:?
第一個(gè)參數(shù)af是地址族,轉(zhuǎn)換后存在dst中
af = AF_INET:src為指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函數(shù)將該地址轉(zhuǎn)換為in_addr的結(jié)構(gòu)體,并復(fù)制在*dst中
af =AF_INET6:src為指向IPV6的地址,函數(shù)將該地址轉(zhuǎn)換為in6_addr的結(jié)構(gòu)體,并復(fù)制在*dst中
如果函數(shù)出錯(cuò)將返回一個(gè)負(fù)值,并將errno設(shè)置為EAFNOSUPPORT,如果參數(shù)af指定的地址族和src格式不對,函數(shù)將返回0。
測試:
編譯server.c
gcc -o server server.c
啟動(dòng)進(jìn)程:
./server
顯示結(jié)果:
======waiting for client's request======
并等待客戶端連接。
編譯 client.c
gcc -o client server.c
客戶端去連接server:
./client 127.0.0.1?
等待輸入消息

發(fā)送一條消息,輸入:c++

此時(shí)服務(wù)器端看到:

客戶端收到消息:
