服務(wù)器端
步驟
- 創(chuàng)建一個(gè)socket套接字文件描述符
int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - 創(chuàng)建一個(gè)sockaddr_in結(jié)構(gòu)體的變量荣德,并配置相應(yīng)的參數(shù)滚停,然后綁定
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //先清除變量值
serv_addr.sin_family = AF_INET; //表示使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //IP地址
serv_addr.sin_port = htons(1234); //配置通信端口
bind(serv_sock, (struct sockaddr)serv_addr, sizeof(serv_addr)); //綁定
知識(shí)點(diǎn):
a. AF_INET:表示使用IPv4的IP地址鼻百,IPv4的IP地址用AF_INET6*
b. inet_addr()函數(shù):將一個(gè)點(diǎn)分十進(jìn)制IP地址轉(zhuǎn)換為長(zhǎng)整型(unsigned long)的變量拗小,127.0.0.1表示本機(jī)地址
c. hton()函數(shù):將整型變量從主機(jī)字節(jié)順序轉(zhuǎn)變成網(wǎng)絡(luò)字節(jié)順序(高位字節(jié)存放在內(nèi)存的低地址處萍桌。)
d. bind:將套接字serv_sock與IP地址和端口綁定在一起(存儲(chǔ)在serv_addr中) - 進(jìn)入監(jiān)聽(tīng)狀態(tài)柠掂,等待用戶發(fā)送請(qǐng)求
listen(serv_sock, 20); //對(duì)serv_sock套接字進(jìn)行監(jiān)聽(tīng)熊杨,20表示最大允許20個(gè)用戶請(qǐng)求排隊(duì)
讓套接字處于被動(dòng)監(jiān)聽(tīng)狀態(tài)沐兵。所謂被動(dòng)監(jiān)聽(tīng)别垮,是指套接字一直處于“睡眠”中,直到客戶端發(fā)起請(qǐng)求才會(huì)被“喚醒” - 接收客戶端請(qǐng)求
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size = sizeof(clnt_addr);
int clnt_sock = accept(serv_sock, (struct sockaddr*)clnt_addr, &clnt_addr_size);
用來(lái)接收客戶端的請(qǐng)求扎谎。程序一旦執(zhí)行到 accept() 就會(huì)被阻塞(暫停運(yùn)行)碳想,直到客戶端發(fā)起請(qǐng)求。 - 向客戶端發(fā)送數(shù)據(jù)
char str[] = "Hello World!";
write(clnt_sock, str, sizeof(str)); - 關(guān)閉套接字
close(clnt_sock);
close(serv_sock);
完整的服務(wù)端socket代碼如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(){
//創(chuàng)建套接字
int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//將套接字和IP毁靶、端口綁定
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每個(gè)字節(jié)都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具體的IP地址
serv_addr.sin_port = htons(1234); //端口
bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
//進(jìn)入監(jiān)聽(tīng)狀態(tài)胧奔,等待用戶發(fā)起請(qǐng)求
listen(serv_sock, 20);
//接收客戶端請(qǐng)求
struct sockaddr_in clnt_addr;
socklen_t clnt_addr_size = sizeof(clnt_addr);
int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size);
//向客戶端發(fā)送數(shù)據(jù)
char str[] = "Hello World!";
write(clnt_sock, str, sizeof(str));
//關(guān)閉套接字
close(clnt_sock);
close(serv_sock);
return 0;
}
客戶端
步驟
- 創(chuàng)建一個(gè)套接字
int sock = socket(AF_INET, SOCK_STREAM, 0); - 創(chuàng)建需要連接的服務(wù)器的sockaddr_in結(jié)構(gòu)體的變量,并配置相應(yīng)的參數(shù)预吆,然后連接
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每個(gè)字節(jié)都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //因?yàn)槲覀冞B接的服務(wù)器端在本機(jī)上龙填,所以該地址為本機(jī)地址
serv_addr.sin_port = htons(1234); //端口
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
注:connect向服務(wù)器發(fā)起請(qǐng)求,服務(wù)器的IP地址和端口號(hào)保存在 sockaddr_in 結(jié)構(gòu)體中拐叉。直到服務(wù)器端返回?cái)?shù)據(jù)岩遗,connect才結(jié)束。 - 讀取服務(wù)器端返回的數(shù)據(jù)
char bufRecv[100] = {0};
read(sock, bufRecv, 100);
printf("Message form server: %s\n", bufRecv); - 關(guān)閉套接字
close(sock);
完成的代碼如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(){
//創(chuàng)建套接字
int sock = socket(AF_INET, SOCK_STREAM, 0);
//向服務(wù)器(特定的IP和端口)發(fā)起請(qǐng)求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每個(gè)字節(jié)都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具體的IP地址
serv_addr.sin_port = htons(1234); //端口
connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
//讀取服務(wù)器傳回的數(shù)據(jù)
char buffer[40];
read(sock, buffer, sizeof(buffer)-1);
printf("Message form server: %s\n", buffer);
//關(guān)閉套接字
close(sock);
return 0;
}