You should choose integer over string if the values an integer can have and the operations an integer supports are a better fit for the data in question than the values and operations a string has.
It is okay if some of the values/operations of that type don't make sense for that data, simply because there are so many different kinds of real-world data that if we tried to make all databases and programming languages have separate built-in types that perfectly matched them, we'd never get any real work done.
First, IP addresses. Assuming for simplicity we only care about IPv4 addresses, then RFC 760 says "Addresses are fixed length of four octets (32 bits)." This immediately tells us that the set of possible values for a 32-bit unsigned integer is exactly the same as the set of valid IP addresses. A string representation would in principle allow all sorts of clearly invalid IP addresses like "9999.9999.9999.-42e5" and "Hello World!" unless we write a bunch of validation code. That alone is more than enough reason to use integers as your "backend" representation of IP addresses, even if the rest of your code prefers to use a string or some object with a pretty printing method to ensure you normally get the "dot-decimal" notation humans like. If another argument is required, note that part of the reason dot-decimal notation for IP addresses is so common is that the four 8-bit components of an IP address often have separate meanings. Thus, we'll probably want to extract those four separate 8-bit numbers from an IP address from time to time, and taking the first or last 8 bits of a 32-bit integer is a much simpler and faster operation than tokenizing a string.
Then we have port numbers. The TCP and UDP protocols define a port as a 16-bit unsigned integer, so once again, that more or less settles that. But another argument that applies to ports is that there are many important "ranges" of ports, such as 0 to 1023 being the "well-known ports" used by system processes, and these ranges are obviously defined with integer ordering in mind rather than string ordering. No one in their right mind would claim port 50 falls outside the range of well-known ports just because the string "50" is greater than the string "1023".
You'll notice that in both of these examples, I did not describe any "calculations" such as addition or subtraction, so the literal answer to your question is "no". I don't know of any situation where it would make sense to add two IP addresses or port numbers. Again, most real-world data will never be a perfect fit for any type we give it.
And since I argued for "integer" on both of those examples, let me include a few counterexamples: phone numbers and street addresses. For street addresses I probably don't even have to make any arguments; it's just so obvious that no numeric type could ever hope to represent that sort of information adequately. For phone numbers it's less obvious, but consider the following: the length of a phone number varies by country; the length is always measured in digits, not in bits/bytes/octets; various symbols like +, # and () are sometimes used to represent important information like country codes and area codes; I can't think of any reason to add, subtract or compare two phone numbers; extracting a country code or area code from a complete phone number is a genuine string tokenization problem we can't reduce to a bit shift operation because all of the above have variable lengths.