Sockets Tutorial 对C语言的socket编程做了详细描述,这里记录一下
服务端程序:
/*
* server.c
*
* Created on: 2016-7-26
* Author: qiu
*/
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(char *msg) {
perror(msg);
exit(1);
}
int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
/* Allocate a new socket,Returns a file descriptor for the new socket, or -1 for errors. */
//the first is the address domain of the socket. recall that there are two possile address domains
//the unic domain for two processes which share a common file system, and the internet domain for
//any two hosts on the Internet. The symbol constant AF_UNIX is used for the former, and
//AF_INET is used for the latter
//第二个参数表示类型,SOCK_STREAM表示TCP,SOCK_DGRAM表示UDP
//这个函数返回an entry into the file descriptor table (i.e. a small integer),this value is used for all
// subsequent references to this socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
//portno = atoi(argv[1]);
portno = 51717;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY; //这个INADDR_ANY是一个常量0,在服务端就是这个样子?表示本机地址
serv_addr.sin_port = htons(portno);
//将一个socket绑定到一个地址
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
//listen的第二个参数is the size of the backlog queue,i.e., the number of connections that can be
//waiting while the process if handling a particular connection
listen(sockfd, 5);
clilen = sizeof(cli_addr);
//accept一直阻塞,一直等到一个client连接到server,返回一个新的文件描述符,所有的通信都由新的描述符完成
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
//这里只接收256个字符,超过的被截断了
bzero(buffer, 256);
n = read(newsockfd, buffer, 255);
if (n < 0)
error("ERROR reading from socket");
printf("Here is the message: %s\n", buffer);
//往文件描述符里写信息
n = write(newsockfd, "I got your message", 18);
if (n < 0)
error("ERROR writing to socket");
return 0;
}
客户端程序:
/*
* client.c
*
* Created on: 2016-7-26
* Author: qiu
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(char *msg) {
perror(msg);
exit(0);
}
int main(int argc, char *argv[]) {
int sockfd, portno, n;
struct sockaddr_in serv_addr;
//struct hostent defines a host computer on the Internet
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr, "usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
//通过域名获取关于服务器的描述
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr, "ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *) server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
//establish a connection to the server
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the message: ");
bzero(buffer, 256);
//从标准输入获取字符,并写入到socket的文件描述符中
fgets(buffer, 255, stdin);
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer, 256);
n = read(sockfd, buffer, 255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n", buffer);
return 0;
}