網路程式設計——tcp伺服器
阿新 • • 發佈:2019-01-01
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h> #define PORT 9998 void handl_client(int client_socket) { char buf[1024] = {"asdsadsadsadsa"}; while (1) { int ret = read(client_socket, buf, sizeof(buf)-1); if (-1 == ret) { perror ("read error"); } if (0 == ret) { printf ("客戶端退出\n"); break; } buf[ret] = '\0'; printf ("收到客戶端資料:%s\n", buf); int i; for (i = 0; i < ret-1; i++) { buf[i] += 'A' - 'a'; } write(client_socket, buf, ret); } } int main(int argc, char **argv) { // 1、建立套接字 // 第一個引數:使用的協議族 // 第二個引數:使用的協議型別 // 第三個引數:一般寫 0 int listen_socket = socket(AF_INET, SOCK_STREAM, 0); if(-1 == listen_socket) { perror("建立套接字失敗"); return -1; } struct sockaddr_in addr; memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; /* Internet地址族 */ addr.sin_port = htons(PORT); /* 埠號 */ addr.sin_addr.s_addr = htonl(INADDR_ANY); /* IP地址, 繫結本地的所有ip地址*/ // 2、繫結本地的 ip 地址和埠 // 第一個引數:需要繫結的套接字 // 第二個引數:是要繫結的ip和埠 // 第三個引數:第二個引數所佔的位元組數 int ret = bind(listen_socket, (const struct sockaddr *)&addr, sizeof(addr)); if(-1 == ret) { perror("繫結失敗"); return -1; } // 3、監聽套接字 ret = listen(listen_socket, 5); if(-1 == ret) { perror("監聽失敗"); return -1; } printf ("等待客戶端連線.........\n"); // 4、處理客戶端的連線 // accept 是一個阻塞型函式,如果沒有客戶端連線,會一直阻塞 // 第一個引數:需要監聽的套接字 // 第二個引數:如果成功建立連線,該引數儲存的是連線的客戶端的ip地址和埠 // 第三個引數:客戶端地址的長度,該引數是一個傳入傳出引數,不能寫NULL // 返回值:如果成功連線,返回一個用於和客戶端通訊的套接字,不是之前的監聽套接字,注意區分 struct sockaddr_in client_addr; socklen_t len = sizeof(client_addr); int client_socket = accept(listen_socket, (struct sockaddr *)&client_addr, &len); if (-1 == client_socket) { perror("accept 失敗"); return -1; } printf ("客戶端的 ip = %s, 埠 = %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); handl_client(client_socket); return 0; }