网络是大端
发数据从低地址发, 先发的是 高位的数据。
收数据从高位收,先收到的数据存放到低地址。
TCP 是 流式的 所用套接字也是流式的
文件描述符
socket 是 IP 加 端口号
用到的函数:
int socket(int domain, int type, int protocol); int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int inet_aton(const char *cp, struct in_addr *inp); in_addr_t inet_addr(const char *cp); in_addr_t inet_network(const char *cp); char *inet_ntoa(struct in_addr in); struct in_addr inet_makeaddr(int net, int host); in_addr_t inet_lnaof(struct in_addr in);
查找头文件中的类型定义
grep -ER
练习代码:【服务器 阻塞式的 只能处理一个请求】
/******
* 阻塞式的
*
* **********/
#include<stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <errno.h>
#include<string.h>
#include <arpa/inet.h>
//#include <unistd.h>
#define _PORT_ 9999
#define _BACKLOG_ 10 // 监听端口 队列长度
int main()
{
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
printf("create socket error, error is : %d, errstring is : %s\n", errno, strerror(errno));
return 1;
}
struct sockaddr_in server_socket;
struct sockaddr_in client_socket;
bzero(&server_socket, sizeof(server_socket));
server_socket.sin_family = AF_INET;
server_socket.sin_addr.s_addr = htonl(INADDR_ANY);
server_socket.sin_port = htons(_PORT_);
if (bind(sock, (struct sockaddr*)&server_socket, sizeof(struct sockaddr_in)) < 0)
{
printf("bind error, error code is : %d, errno string is :%s\n", errno, strerror(errno));
close(sock);
return 2;
}
if (listen(sock, _BACKLOG_) < 0)
{
printf("listen error , errno code is :%d, errno string is :%s\n", errno, strerror(errno));
close(sock);
return 3;
}
printf("bind and listen success, wait accept...\n");
while (1)
{
socklen_t len = 0;
int client_sock = accept(sock, (struct sockaddr *)&client_sock, &len);
if (client_sock < 0)
{
perror("accept");
close(sock);
return 4;
}
char buf[1024];
memset(buf, '\0', sizeof(buf));
inet_ntop(AF_INET, &client_socket.sin_addr, buf, sizeof(buf));
printf("get connect, ip is :%s port is : %d\n", buf,ntohs(client_socket.sin_port));
while (1)
{
memset(buf, '\0', sizeof(buf));
read(client_sock, buf, sizeof(buf) - 1);
printf("client : %s\n", buf);
printf("server :");
memset(buf, '\0', sizeof(buf));
// fgets(buf, sizeof(buf), stdin);
// buf[strlen(buf) - 1] = '\0';
write(client_sock, buf, strlen(buf)+1);
printf("please wait...\n");
}
}
close(sock);
return 0;
}
运行:
查看监听状态
[bozi@localhost ~]$ netstat -nltp (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:9999 0.0.0.0:* LISTEN 10091/./server_1_si tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN - tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:60790 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN - tcp 0 0 :::47946 :::* LISTEN - tcp 0 0 :::111 :::* LISTEN - tcp 0 0 :::22 :::* LISTEN - tcp 0 0 :::23 :::* LISTEN - tcp 0 0 ::1:631 :::* LISTEN - tcp 0 0 ::1:25 :::* LISTEN -
测试的时候 用 telnet
telnet CTRL+] 就可以进入命令行了
问题描述:服务器与 客户端连接后 马上 kill掉服务器 然后又启动服务器 出现 Address already in use的错误 linux中等上半分钟 就可以启动服务器了
[bozi@localhost tcp]$ ./server_1_simple
bind and listen success, wait accept...
get connect, ip is :13.0.0.0 port is : 1032
^C
[bozi@localhost tcp]$ ./server_1_simple
bind error, error code is : 98, errno string is :Address already in use
原因:
解决方法: