服务器端代码 server.cpp:
#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(){
int serv_sock
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
struct sockaddr_in serv_addr
;
memset(&serv_addr
, 0, sizeof(serv_addr
));
serv_addr
.sin_family
= AF_INET
;
serv_addr
.sin_addr
.s_addr
= inet_addr("127.0.0.1");
serv_addr
.sin_port
= htons(1234);
bind(serv_sock
, (struct sockaddr
*)&serv_addr
, sizeof(serv_addr
));
listen(serv_sock
, 20);
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
);
char str
[] = "http://c.biancheng.net/socket/";
write(clnt_sock
, str
, sizeof(str
));
close(clnt_sock
);
close(serv_sock
);
return 0;
}
客户端代码 client.cpp:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
int main(){
int sock
= socket(AF_INET
, SOCK_STREAM
, 0);
struct sockaddr_in serv_addr
;
memset(&serv_addr
, 0, sizeof(serv_addr
));
serv_addr
.sin_family
= AF_INET
;
serv_addr
.sin_addr
.s_addr
= inet_addr("127.0.0.1");
serv_addr
.sin_port
= htons(1234);
connect(sock
, (struct sockaddr
*)&serv_addr
, sizeof(serv_addr
));
char buffer
[40];
read(sock
, buffer
, sizeof(buffer
)-1);
printf("Message form server: %s\n", buffer
);
close(sock
);
return 0;
}
编译运行
[admin@localhost ~
]$ g++ server.cpp -o server
[admin@localhost ~
]$ ./server
[admin@localhost ~
]$ g++ client.cpp -o client
[admin@localhost ~
]$ ./client
Windows 下的 socket 程序和 Linux 思路相同,但细节有所差别:
Windows 下的 socket 程序依赖 Winsock.dll 或 ws2_32.dll,必须提前加载。
Linux 使用“文件描述符”的概念,而 Windows 使用“文件句柄”的概念;Linux 不区分 socket 文件和普通文件,而 Windows 区分;Linux 下 socket() 函数的返回值为 int 类型,而 Windows 下为 SOCKET 类型,也就是句柄。
Linux 下使用 read() / write() 函数读写,而 Windows 下使用 recv() / send() 函数发送和接收。
关闭 socket 时,Linux 使用 close() 函数,而 Windows 使用 closesocket() 函数。