本示例為 Client/Server 結(jié)構(gòu),通過代碼演示 Client 如何建立連接,并向遠(yuǎn)程端發(fā)送數(shù)據(jù);Server 端如何偵聽系統(tǒng)連接請(qǐng)求,接收請(qǐng)求并建立連接,進(jìn)而獲取客戶端發(fā)來的數(shù)據(jù)。代碼雖短,卻描述了整個(gè)通信過程,可對(duì)Linux 下 網(wǎng)絡(luò)編程起個(gè)拋磚引玉的作用吧 :-)
Client 端代碼:
--------------------------------------------------------------
/* sockclnt.c*/
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /*for struct sockaddr_in*/
#define DEST_IP "65.52.207.217"
#define DEST_PORT 4000
int main()
{
int res;
int sockfd;
struct sockaddr_in dest_addr;
char *msg = "Hello world\n";
int len, bytes_sent;
/* 取得一個(gè)套接字*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1) {
perror("socket()");
exit(1);
}
/* 設(shè)置遠(yuǎn)程連接的信息*/
dest_addr.sin_family = AF_INET; /* 注意主機(jī)字節(jié)順序*/
dest_addr.sin_port = htons(DEST_PORT); /* 遠(yuǎn)程連接端口, 注意網(wǎng)絡(luò)字節(jié)順序*/
dest_addr.sin_addr.s_addr = inet_addr(DEST_IP); /* 遠(yuǎn)程 IP 地址, inet_addr() 會(huì)返回網(wǎng)絡(luò)字節(jié)順序*/
bzero(&(dest_addr.sin_zero), 8); /* 其余結(jié)構(gòu)須置 0*/
/* 連接遠(yuǎn)程主機(jī),出錯(cuò)返回 -1*/
res = connect(sockfd, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_in));
if (res == -1) {
perror("connect()");
exit(1);
}
len = strlen(msg);
bytes_sent = send(sockfd, /* 連接描述符*/
msg, /* 發(fā)送內(nèi)容*/
len, /* 發(fā)關(guān)內(nèi)容長度*/
0); /* 發(fā)送標(biāo)記, 一般置 0*/
/* 關(guān)閉連接*/
close(sockfd);
}
Server 端的代碼:
-----------------------------------------------------------------------------------------
/* socksrv.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h> /* for struct sockaddr_in*/
#define BACKLOG 10
#define MYPORT 4000
int main()
{
char *addr;
int sockfd;
int new_fd;
struct sockaddr_in my_addr, their_addr;
int res;
int sin_size;
char *buf;
/* 取得套接字描述符*/
sockfd = socket(AF_INET, /* domain*/
SOCK_STREAM, /* type*/
0); /* protocol*/
if (sockfd == -1) {
perror("socket");
exit(1);
}
/* Init sockaddr_in */
my_addr.sin_family = AF_INET; /* 注意: 應(yīng)使用主機(jī)字節(jié)順序*/
my_addr.sin_port = htons(MYPORT); /* 注意: 應(yīng)使用網(wǎng)絡(luò)字節(jié)順序*/
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 使用自己的 IP 地址 */
bzero(&(my_addr.sin_zero), 8); /* 結(jié)構(gòu)的其余的部分須置 0*/
/* 指定一個(gè)套接字使用的地址及端口*/
res = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr));
if (res == -1) {
perror("bind");
exit(1);
}
/* 監(jiān)聽請(qǐng)求, 等待連接*/
res = listen(sockfd,
BACKLOG); /* 未經(jīng)處理的連接請(qǐng)求隊(duì)列可容納的最大數(shù)目*/
if (res == -1) {
perror("listen");
exit(1);
}
/* 接受對(duì)方的連接請(qǐng)求, 建立連接,返回一個(gè)新的連接描述符.
* 而第一個(gè)套接字描述符仍在你的機(jī)器上原來的端口 listen()
*/
sin_size = sizeof(struct sockaddr_in);
new_fd = accept(sockfd, (void *)&their_addr, &sin_size);
buf = (char *)malloc(255);
if (buf == NULL) {
printf("malloc failed\n");
exit(1);
}
/* 接受對(duì)方發(fā)來的數(shù)據(jù)*/
res = recv(new_fd, buf, 255, 0);
if (res == -1) {
perror("recv()");
exit(1);
}
/* 關(guān)閉本次連接*/
close(new_fd);
/* 關(guān)閉系統(tǒng)監(jiān)聽*/
close(sockfd);
printf("recv data:%s\n", buf);
free(buf);
return 0;
}
編譯:
------------------------------------------------
gcc -o sockclnt sockclnt.c
gcc -o socksrv socksrv.c