563
社区成员
发帖
与我相关
我的任务
分享我的视频地址: 五分钟入门网络编程(一)
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <pthread.h>
#define PORT 8989
void* clinet_func(void* arg);
int SocketServerInit() {
int ret;
socklen_t len;
struct sockaddr_in addr;
memset(&addr, 0x00, sizeof(addr));
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == -1) {
perror("socket failed\n");
return -1;
}
// IPV4
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(PORT);
len = sizeof(addr);
ret = bind(sock , (struct sockaddr *)&addr, len);
if (ret == -1) {
perror("bind failed\n");
return -1;
}
listen(sock,512);
return sock;
}
int main(int argc, char** argv) {
int cnt;
int client_fd;
// socket bind listen
int sock = SocketServerInit();
struct sockaddr_in client_addr;
memset(&client_addr, 0x00, sizeof(client_addr));
socklen_t len = sizeof(client_addr);
#if 0
int client_fd = accept(sock, (struct sockaddr *)&client_addr, &len);
printf("client_fd = %d\n", client_fd);
char buffer[1024] = {0};
cnt = recv(client_fd, buffer, sizeof(buffer), 0);
printf("cnt = %d buffer = %s\n", cnt, buffer);
len = send(client_fd, buffer, cnt, 0);
if(len != cnt) {
printf("send msg failed, len = %d, buffer len = %ld\n", len, strlen(buffer));
return -1;
}
#elif 0
while(1)
{
client_fd = accept(sock, (struct sockaddr *)&client_addr, &len);
printf("client_fd = %d\n", client_fd);
char buffer[1024] = {0};
cnt = recv(client_fd, buffer, sizeof(buffer), 0);
printf("cnt = %d buffer = %s\n", cnt, buffer);
len = send(client_fd, buffer, cnt, 0);
if(len != cnt) {
printf("send msg failed, len = %d, buffer len = %ld\n", len, strlen(buffer));
return -1;
}
}
#else
pthread_t pid;
while(1)
{
client_fd = accept(sock, (struct sockaddr *)&client_addr, &len);
printf("client_fd = %d\n", client_fd);
if(-1 == pthread_create(&pid, NULL, clinet_func, (void*)&client_fd)) {
printf("pthread_create failed\n");
return -1;
}
}
#endif
getchar();
close(sock);
close(client_fd);
}
void* clinet_func(void* arg) {
int client_fd = *(int*)arg;
int cnt, len;
char buffer[1024] = {0};
cnt = recv(client_fd, buffer, sizeof(buffer), 0);
printf("cnt = %d buffer = %s\n", cnt, buffer);
len = send(client_fd, buffer, cnt, 0);
if (len != cnt) {
printf("send msg failed, len = %d, buffer len = %ld\n", len, strlen(buffer));
return NULL;
}
}
常见错误
Address already in use 端口被占用
查看监听命令(工作中常用命令)
netstat -anop | grep 8989
netstant -anltp | grpe 8989
其他,我工作常用的命令
nc命令,用于模拟客户端或服务端
nc 127.0.0.1 8989 #创建客户端
nc -lk 8989 #创建多进程服务端
当server处于下面代码时候
// ...
while(1) {
int fd = accetp(...);
int cnt = recv(..);
send(...);
//...
}
此时启动服务端处于while循环accept中, 当启动三个客户端建立链接。 此时服务端就有有 客户端1 客户端2 客户端3 等待接受数据。
客户端1还没有发送数据,此时程序阻塞在recv函数, 所以客户端2 和客户端3 发送数据,会没有反应。
第三个客户端发送数据, 没有返回。
第二个客户端发送数据,没有返回。
到最后第一个客户端发送数据,所有客户端都得到相应。
原因:此时三个客户端已经建立链接。 发送数据accept只执行一次然后阻塞在recv函数。再处理新的链接再回发送。
多个IO每来一个链接处理一个请求spawn一个线程处理。
send/recv 返回值
-1 发送失败,
0对方断开链接。
大于0发送字节数量,通过 errno 判断具体错误原因
send函数
send(fd, buffer , buffer length, 0 );
如果buffer 定义为 char buffer[1024];
只往 buffer 里写了 5 个字节,
send依然会尝试发送整个 buffer len 个 字节的缓冲区,这就是 len 返回 1024 的根本原因。
本文参考资料 https://github.com/0voice